所以我从竞赛网站上得到了这个问题,我感到非常困惑。这是:
p [10] [10]的以下哪个内存分配代码完美地证实了数组的经典定义?选项包括:
char **p;
int i;
p = (char**)malloc(10*sizeof(char*));
*p = (char*)malloc(10*sizeof(char));
for(i = i; i<10; i++)
p[i] = p[0] +10*i;
char **p;
int i;
p = (char**)realloc(p, 10*sizeof(char*));
*p = (char*)realloc(p, 10*sizeof(char));
for(i = i; i<10; i++)
p[i] = p[0] +10*i;
char **p = NULL;
int i;
p = (char**)malloc(10*sizeof(char*));
*p = (char*)malloc(10*sizeof(char));
for(i = i; i<10; i++)
p[i] = (char*)realloc(p[i-1], 10*i*sizeof(char));
char **p;
int i;
p = (char**)malloc(10*sizeof(char*));
for(i = i; i<10; i++)
p[i] = (char*)malloc(10*sizeof(char));
我完全不解。任何想法都是最受欢迎的。感谢。
编辑:如果它们都不正确,那么正确的实施是什么?我正在准备一些解释,因为我正准备参加竞争性考试,这些考试要求提出这样的问题(大多数都有明显的“副作用”:()。还编辑了拼写错误。
答案 0 :(得分:2)
无。这个确实:
char (*p)[10] = malloc(10*sizeof(*p));
说明:
p
被声明为指向十个char
的数组的指针。由于它指向一个数组,sizeof(*p)
返回该数组的大小,即10。因此,malloc()
调用为10个这样的数组分配内存,i。即100个字节。
现在,当您在p[3]
中解除指针时,该值是内存一巴掌中的第四个数组。但是,这个值在几乎所有上下文中都会衰减为指向其第一个元素的指针,所以当你说p[3][5]
时,该值是内存slap中第4个数组中的第6个元素。
很抱歉,如果这听起来有点令人困惑,但是当您使用char array[10][10];
声明数组时,它发生的情况确实相同,只是内存来自不同的地方。
答案 1 :(得分:1)
首先要做的事:do not cast the return value of malloc in C。这不是你的代码,但无论如何,说这总是好的
此外,循环应该像这样重写:for(i = 1; i < 10; i++)
或for(i = 0; i < 10; i++)
。 i = i
可能是一个错误(那个网站又是什么?),我会假设。
char **p;
int i;
p = malloc(10*sizeof(char*));
*p = malloc(10*sizeof(char));
for(i = 1; i < 10; i++)
p[i] = p[0] + 10*i;
此第一个代码将10 char*
分配给p
,然后分配10 char
到*p
,相当于p[0]
。然后,它将未分配的2D数组的地址放入i的其他值p[i]
中,从1到9.由于未分配数组(或仅部分分配 - p[0]
),这是非常糟糕。
char **p;
int i;
p = realloc(p, 10*sizeof(char*));
*p = realloc(p, 10*sizeof(char));
for(i = 1; i < 10; i++)
p[i] = p[0] + 10*i;
第二个代码使用realloc
代替malloc
,这不会解决以前的问题,但也会增加可能的分段错误:realloc
对未初始化的指针来说是一个坏主意。< / p>
char **p = NULL;
int i;
p = malloc(10*sizeof(char*));
*p = malloc(10*sizeof(char));
for(i = 1; i < 10; i++)
p[i] = realloc(p[i-1], 10*i*sizeof(char));
第三个代码与第一个代码的第一个代码相同,但是然后在realloc
上使用p[i]
来从0开始。我假设realloc
释放你传递的指针它,所以这不是一个好主意。 10*i*sizeof(char)
也不是一个好主意。基本上,您将p[9]
分配90 char
,而不是其他任何内容。而且,顺便说一下,将p
初始化为NULL
并不做任何事情。
char **p;
int i;
p = malloc(10*sizeof(char*));
for(i = 0; i < 10; i++)
p[i] = malloc(10*sizeof(char));
这第四个代码至少有一些好处:它为i分别为每个p[i]
分配0到9(我假设我在这里从0开始,与其他代码不同)。所以,这可能是你正在寻找的答案。
最后,由于这些代码与char p[10][10]
之类的声明没有相同的语义,因此问题很难解决。
修改:
如果您想要动态分配的2D阵列,可以使用它,例如:
int i;
char **p = malloc(10 * sizeof *p);
for(i = 0; i < 10; i++)
p[i] = malloc(10 * sizeof *p[i]);
您也可以像cmaster那样使用指向数组类型的指针(如char[10]
)。这是来自cmaster的例子:char (*p)[10]
。
答案 2 :(得分:0)
p[1][0]
(以及其他)指向无效的内存位置。realloc()
。[1, 10)
循环,我希望[0, 10)
。所以它也很可怕。所有这些都很可怕。正确的代码是:
char (*p)[10] = malloc(10 * sizeof(*p));
或者:
char **p = malloc(10 * sizeof(*p));
for (int i=0; i<10; ++i)
p[i] = malloc(10 * sizeof(**p));