2012-07-23 167 views
-4

我卡住了,无法弄清楚为什么这是下面的一段代码没有运行。我是相当新的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 **? 谢谢

+1

看来,你对指针的工作方式并没有很好的掌握。从这些行中:'char ** arr2 = NULL;' 'arr2 [0] = arr;' 'arr2 [1] = arr1;' – OmnipotentEntity 2012-07-23 07:10:20

+0

在第二种情况下,它不能正常工作:变量在堆栈上。 – nhahtdh 2012-07-23 07:11:18

+0

如果您在C++中停止使用原始字符数组并使用字符串类,则所有问题都会消失。将'#include '添加到代码文件的顶部,并用'std :: string'替换所有这些混乱。 – 2012-07-23 07:16:20

回答

3

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

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

底线,您的版本都不正确。第二个变种是“运行完美”只是提醒你多出来的代码可以出现正常运行,直到疏忽编程真的咬你你以后,让你浪费时间和日子在调试,因为你抛弃了堆栈。

编辑:而且 “罪行” 中的代码:

  1. 字符串文字char const *类型,难道你忘了const
  2. 缩进函数的代码是很常见的(也是推荐的)。
  3. 这是(恕我直言)良好的做法,在各地增加空间,以提高可读性(例如后(,前),前后二元运算符,后;for声明等)。口味不同,有一个声音派别,实际上鼓励留出空间尽可能,但你并没有做一致 - 和一致性 universially建议。尝试代码重新格式化,如astyle,看看他们可以做些什么来提高可读性。
+0

它们也不正确,因为C++中的字符常量是'const'。任何体面的编译器都应该发出警告。 – 2012-07-23 07:17:09

+0

@CodyGray:其实我看起来并没有那么远,并且在答案中,甚至连提*这样的东西(或者非缩进,非间距的可怕代码风格)都太失望了。这就像对聋哑人讲道一样。 – DevSolar 2012-07-23 07:20:54

+0

正是我为什么停止写一个答案,并+ 1'刚刚出现与重要的事情在黑体。 :-) – 2012-07-23 07:51:25

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; 
0

简单地说,指针的声明不会保留任何内存,而数组的declration不会。

在你的第一个例子中 你的行char ** arr2 = NULL声明了一个指向字符指针的指针,但没有将它设置为任何值 - 因此它开始指向零字节(NULL == 0)。当你说arr2 [0] =你试图将一个不属于你的值置于零的位置时 - 这就是崩溃。

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

+1

声明不一定保留任何内存,但定义确实如此,并且他的所有声明都是定义。问题在于,他所拥有的是指针的定义只会用指针类型创建一个对象。他用一个空指针进行初始化 - 尽管如此。他在第一种情况下的问题是他解除引用空指针。 – 2012-07-23 07:28:31

1
char **arr2=NULL; 

是一个指针,指向空而

char *arr2[1]; 

是已分配的空间的指针用于两个项目的数组的指针。

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

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

说实话,自从我上次以来我一直在处理这些东西,但是在这里可以用this little tutorial来处理,可能会清除C++中数组和指针的运动。