使用指针和内存分配的经典阵列实现

时间:2014-08-27 16:47:46

标签: c arrays pointers

所以我从竞赛网站上得到了这个问题,我感到非常困惑。这是:

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

我完全不解。任何想法都是最受欢迎的。感谢。

编辑:如果它们都不正确,那么正确的实施是什么?我正在准备一些解释,因为我正准备参加竞争性考试,这些考试要求提出这样的问题(大多数都有明显的“副作用”:()。还编辑了拼写错误。

3 个答案:

答案 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)

好吧,让我们看看:

  1. 这可能会导致错误,因为p[1][0](以及其他)指向无效的内存位置。
  2. 这是未定义的行为,因为您将未初始化的指针传递给realloc()
  3. 该代码可能会在整个地方留下未经初始化的指针。
  4. 此代码从[1, 10)循环,我希望[0, 10)。所以它也很可怕。
  5. 因此:

    所有这些都很可怕。正确的代码是:

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