为什么这会失败

时间:2012-07-23 07:07:51

标签: c++

我陷入困境,无法弄清楚为什么以下这段代码没有运行。我对c / c ++很新。

#include <iostream>
int main(){
    const char *arr="Hello";
    const char * arr1="World";

    char **arr2=NULL;
    arr2[0]=arr;
    arr2[1]=arr1;

    for (int i=0;i<=1;i++){
        std::cout<<arr2[i]<<std::endl;
    }
    return 0;
}

这里运行得很好

#include <iostream>
int main(){

    const char *arr="Hello";
    const char * arr1="World";

    char *arr2[1];
    arr2[0]=arr;
    arr2[1]=arr1;

    for (int i=0;i<=1;i++){
        std::cout<<arr2[i]<<std::endl;
    }
    return 0;
} 

这是为什么?一般如何迭代char **? 谢谢

4 个答案:

答案 0 :(得分:3)

char *arr2[1];是一个数组,其中一个元素(在堆栈上分配)类型为“指向char的指针”。 arr2[0]是该数组中的第一个元素。 arr2[1]未定义。

char **arr2=NULL;是指向“char指针”的指针。请注意,堆栈上分配了 no 内存。 arr2[0]未定义。

底线,你的两个版本都不正确。第二个版本“运行完美”只是提醒一下,错误的代码出现才能正常运行,直到疏忽编程真的咬你你以后会让你浪费时间和日子进行调试,因为你破坏了堆栈。

修改:代码中的其他“违规行为”:

  1. 字符串文字的类型为char const *,您不会忘记const
  2. 通常(并推荐)练习缩进函数的代码。
  3. (IMHO)好的做法是在各个地方添加空格以提高可读性(例如发布(,预),前后二元运算符,;后发布{ {1}}声明等)。口味不同,并且有一个声音派系实际上鼓励尽可能地留下空格,但你甚至没有那个一致 - 和一致性 普遍推荐。尝试像astyle这样的代码重新格式化,看看他们可以做些什么来提高可读性。

答案 1 :(得分:1)

这是不正确的,因为arr2没有指向任何东西:

char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;

正确的方法:

char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;

这也是错误的,arr2的大小为1:

char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;

正确的方法是一样的:

char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;

答案 2 :(得分:1)

char **arr2=NULL;

指向

时指向NULL的指针的指针
char *arr2[1];

是一个指针数组,已经为两个项目分配了空间。

在指向指针的第二种情况下,您正在尝试在不存在的内存位置写入数据,而在第一个位置,编译器已经为该数组分配了两个内存槽,因此您可以分配值这两个要素。

如果您非常简单地想到它,C指针只是一个整数变量,其值实际上是一个内存地址。因此,通过定义char *x = NULL,您实际上定义了一个值为NULL的整数变量(即零)。现在假设你写了*x = 5之类的东西;这意味着转到存储在x(NULL)中的内存地址并在其中写入5。由于没有地址为0的内存插槽,整个语句都会失败。

说实话吧;自从我上次不得不处理这些东西以来已经很久了,但this little tutorial在这里,可能会清除C ++中数组和指针的运动。

答案 3 :(得分:0)

简单地说,指针的声明不会保留任何内存,因为数组的解除不会。

在你的第一个例子中 你的行char ** arr2 = NULL声明一个指向字符指针的指针,但是没有将它设置为任何值 - 因此它被指向零字节(NULL == 0)。当你说arr2 [0] =某事你试图在这个零位置放置一个不属于你的地方 - 从而导致崩溃。

在你的第二个例子中: 声明* arr2 [2]确实为两个指针保留空间,因此它可以工作。