C 另一个动态内存分配错误

C 另一个动态内存分配错误,c,pointers,malloc,dynamic-memory-allocation,C,Pointers,Malloc,Dynamic Memory Allocation,我试图为多维数组(8行3列)分配内存 这是分配的代码(我相信错误对您来说是清楚的) 中0x0135144d处未处理的异常 xxxx.exe: 0xC0000005:访问冲突写入 位置0xabababab 这类主题有没有推荐的参考资料/阅读资料 谢谢。我现在还不知道任何关于内存分配的书,但是任何介绍性的C教程都应该解释一下。至于bug,您的for循环只初始化前3行,而不是您分配的8行。应该是: for (i = 0; i < 8; i++) malloc(sizeof(char*) * 8

我试图为多维数组(8行3列)分配内存

这是分配的代码(我相信错误对您来说是清楚的)

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

这类主题有没有推荐的参考资料/阅读资料


谢谢。

我现在还不知道任何关于内存分配的书,但是任何介绍性的C教程都应该解释一下。至于bug,您的
for
循环只初始化前3行,而不是您分配的8行。应该是:

for (i = 0; i < 8; i++)
malloc(sizeof(char*) * 8)
char **ptr = (char **) malloc( sizeof(char*) * 8)
(i=0;i<8;i++)的

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

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

如果您使用常量,例如:

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

char **ptr = (char **) malloc( sizeof(char *) * STRING_COUNT);
第一个
malloc()
错误。应该是:

for (i = 0; i < 8; i++)
malloc(sizeof(char*) * 8)
char **ptr = (char **) malloc( sizeof(char*) * 8)
char*
是4字节(或8字节…见第页),而
char
是1字节。当您编写
ptr[3]
时,编译器将假定您想要访问
ptr
+
3*sizeof(char*)
的基址。因此,您将访问未分配的内存

p.S:


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

有两个问题

首先,正如其他人所指出的,您最初的malloc应该是

malloc(sizeof(char*)*8)


第二,您正在初始化8元素数组中的第一个三个元素,但是
ptr[3][0]
指的是第四个元素。因此崩溃。

ptr
是一个由8个指针组成的数组,而不是字符,因此第一行应该是:

for (i = 0; i < 8; i++)
malloc(sizeof(char*) * 8)
char **ptr = (char **) malloc( sizeof(char*) * 8)
因为有8个指针,所以循环应该从0到7:

for (i = 0; i < 8; i++)
最后一点:

ptr[i] = (char *) malloc( sizeof(*ptr[i]) * 3);

规则是:总是取解引用左值的
sizeof
。如果左值为
ptr
,则需要
sizeof(*ptr)
ptr[i]
变为
sizeof(*ptr[i])

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

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

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

第一次分配应该如下所示

char **ptr = malloc( 8 * sizeof *ptr );
pointer = malloc( count * sizeof *pointer );
请记住这是一种通用模式:
malloc
请求通常应如下所示

char **ptr = malloc( 8 * sizeof *ptr );
pointer = malloc( count * sizeof *pointer );
注:上述语句中未提及类型名称


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

@M4的设计也是正确的;有两个bug,我没有注意到<代码> MalCal一个,所以请确保您修复了不幸的是,C++要求您进行强制转换,因此如果需要编写对两者都有效的代码,则需要。@ Matthew Flaschen:是的,但是这个问题被标记了。此外,“编写对两个都有效的代码”的问题通常只适用于头文件。除非你在头文件中写一个内联函数或宏,否则外壳(或不是铸造)<代码> MalOC 通常不会出现与C++兼容性相关的问题。