我正在尝试为多维数组(8行,3列)分配内存。
这是分配的代码(我确定错误很清楚)
char **ptr = (char **) malloc( sizeof(char) * 8);
for (i = 0; i < 3; i++)
ptr[i] = (char *) malloc( sizeof(char) * 3);
当我引用崩溃时发生崩溃:
ptr[3][0];
0x0135144d处的未处理异常 XXXX.EXE: 0xC0000005:访问冲突写入 位置0xabababab。
是否有针对此类主题的推荐参考/读物?
感谢。
答案 0 :(得分:8)
第一个malloc()
错了。它应该是:
malloc(sizeof(char*) * 8)
char*
是4字节(或8字节...见P.S),而char
是1字节。当您编写ptr[3]
时,编译器将假定您要访问ptr
+ 3*sizeof(char*)
的基址。因此,您将访问未分配的内存。
<强> P.S:强>
更准确地说,char*
在32位系统上是4字节,在64位系统上是8字节。
答案 1 :(得分:6)
我不知道任何有关内存分配的书籍,但任何介绍性的C教程都应该解释它。至于你的bug,你的for
循环只初始化前3行,而不是你分配的8行。它应该是:
for (i = 0; i < 8; i++)
答案 2 :(得分:4)
char **ptr = (char **) malloc( sizeof(char *) * 8);
之前,你为8个字符分配空间。你想要8个指向char的空间。
迈克尔指出了另一个错误,从你从未分配的字符串中写下第一个字符。如果使用常量,可能会有所帮助,例如:
const int STRING_COUNT = 8;
const int STRING_LEN = 2;
char **ptr = (char **) malloc( sizeof(char *) * STRING_COUNT);
答案 3 :(得分:3)
ptr
是一个包含8个指针的数组,而不是char
s,所以第一行应该是:
char **ptr = (char **) malloc( sizeof(char*) * 8)
因为有8个指针,所以循环应该从0到7:
for (i = 0; i < 8; i++)
您还可以考虑使用第一行不太容易出错的版本:
char **ptr = (char **) malloc( sizeof(*ptr) * 8)
最后一个:
ptr[i] = (char *) malloc( sizeof(*ptr[i]) * 3);
规则是:始终取用sizeof
解除引用的左值。如果左值为ptr
,则需要sizeof(*ptr)
。 ptr[i]
变为sizeof(*ptr[i])
。
答案 4 :(得分:3)
您的代码中存在多个错误/不一致,但第一个主要问题是第一次分配中的错误sizeof
。如果您遵循一些良好实践指南,则可以轻松避免您所犯的错误:
(1)尽可能避免在语句中使用类型名称。类型名称属于声明,而不是语句。
(2)不要转换内存分配函数的结果。
第一次分配应如下所示
char **ptr = malloc( 8 * sizeof *ptr );
尝试记住这是一种通用模式:malloc
请求通常应如下所示
pointer = malloc( count * sizeof *pointer );
注意:上述声明中未提及任何类型名称。
当然,您还应该考虑2D阵列的第一个尺寸。您尝试分配8,然后您只初始化3.为什么?
答案 5 :(得分:1)
有两个问题。
首先,正如其他人所指出的那样,你的初始malloc应该是
malloc(sizeof(char *)* 8)
其次,您正在初始化8元素数组中的第一个三个元素,但ptr[3][0]
指的是第四个元素。因此崩溃。