0

我正在尝试为多维数组(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];

xxxx.exe 中 0x0135144d 处未处理的异常:0xC0000005:访问冲突写入位置 0xabababab。

这类主题有推荐的参考资料/读物吗?

谢谢。

4

6 回答 6

8

第一个malloc()是错误的。它应该是:

malloc(sizeof(char*) * 8)

Achar*是 4 字节(或 8 字节......见 PS),而char1 字节。当您编写时ptr[3],编译器会假定您要访问ptr+的基地址3*sizeof(char*)。因此,您将访问未分配的内存。

PS:

更准确地说,char*在 32 位系统上是 4 字节,在 64 位系统上是 8 字节。

于 2010-06-02T16:00:06.330 回答
6

我不知道任何关于内存分配的书,但是任何介绍性的 C 教程都应该解释它。至于您的错误,您的for循环仅初始化前 3 行,而不是您分配的 8 行。它应该是:

for (i = 0; i < 8; i++)
于 2010-06-02T15:58:58.027 回答
4
char **ptr = (char **) malloc( sizeof(char *) * 8);

之前,您为 8 个字符分配空间。您需要 8 个指向 char 的指针的空间。

Michael 指出了另一个错误,即从您从未分配的字符串中写入第一个字符。

如果您使用常量可能会有所帮助,例如:

const int STRING_COUNT = 8;
const int STRING_LEN = 2;

char **ptr = (char **) malloc( sizeof(char *) * STRING_COUNT);
于 2010-06-02T15:59:12.223 回答
3

ptr是一个由 8 个指针组成的数组,而不是chars,所以第一行应该是:

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解引用的左值。如果 lvalue 是ptr,那么你需要sizeof(*ptr). ptr[i]变成sizeof(*ptr[i]).

于 2010-06-02T16:05:09.760 回答
3

您的代码中有几个错误/不一致,但第一个主要错误sizeof是第一次分配中的错误。如果您遵循一些良好的实践指南,您所犯的错误很容易避免:

(1)尽可能避免在语句中使用类型名称。类型名称属于声明,而不是语句。

(2)不要强制转换内存分配函数的结果。

第一次分配应该如下所示

char **ptr = malloc( 8 * sizeof *ptr );

试着记住这是一个通用模式:malloc请求通常应该如下所示

pointer = malloc( count * sizeof *pointer );

注意:上述声明中没有提到类型名称。

当然,您还应该决定 2D 数组的第一个大小。您尝试分配 8,然后您只初始化 3。为什么?

于 2010-06-02T16:08:21.780 回答
1

有两个问题。

首先,正如其他人指出的那样,您的初始 malloc 应该是

malloc(sizeof(char *) * 8)

其次,您正在初始化8 元素数组中的前三个ptr[3][0]元素,但引用的是第四个元素。从而崩溃。

于 2010-06-02T16:04:12.977 回答