运行时结构的c数组的大小

时间:2016-03-21 23:58:32

标签: c arrays pointers struct

我需要创建一个结构数组。直到我运行该程序,我才知道我需要在阵列中存储多少结构。计划是将指向结构的指针传递给一个函数,该函数将数据读入其中,但我犯了一个愚蠢的错误。这里有一些代码来说明我尝试做的事情:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

typedef struct {
    int myVar;
} myStruct;

myStruct *myBigList = NULL; 

int defineMyList(myStruct **myArray) {  
    int i = 0, size = rand() % 10;
    *myArray = malloc(size * sizeof *myArray);

    for (i = 0; i < size; i++) {
        myStruct *aStruct = malloc(sizeof(myStruct));
        aStruct->myVar = i + 1;
        myArray[i] = aStruct;
    }
    return size;
}

int main() {
    int size = 0, i = 0;
    srand(time(NULL));

    size = defineMyList(&myBigList);

    for (i = 0; i < size; i++)
        printf("myBigList[%i].myVar: %i\n", i, myBigList[i].myVar);

    return EXIT_SUCCESS;
}

我改编了another question的代码,这个代码有类似我的问题。

我的问题是,当我在将数据输入数据后尝试在main中打印出数组时,我得到了这个:

myBigList[0].myVar: 1
myBigList[1].myVar: 0
myBigList[2].myVar: 0
myBigList[3].myVar: 0
myBigList[4].myVar: 0

当我期待这个时:

myBigList[0].myVar: 1
myBigList[1].myVar: 2
myBigList[2].myVar: 3
myBigList[3].myVar: 4
myBigList[4].myVar: 5

我怀疑我误解了索引和指针的内容。当我使用valgrind运行程序时,它会报告"Invalid read of size 4 at 0x40074D: main""Address 0x51fc0d4 is 0 bytes after a block of size 4 alloc'd at 0x4C2AB80: malloc"

3 个答案:

答案 0 :(得分:4)

你对间接感到困惑。改为:

int defineMyList(myStruct **myArray)
{   
  int i = 0, size = rand() % 10;
  *myArray = malloc(size * sizeof **myArray);  // Note two **

  for(i = 0; i < size; i++) {
    (*myArray)[i].myVar = i + 1;
  }

  return size;
}

甚至更好,完全避免混淆间接:

int defineMyList(myStruct **myArray)
{   
  int i = 0, size = rand() % 10;

  myStruct * new_array = malloc(size * sizeof *new_array);
  if ( !new_array ) {
      perror("couldn't allocate memory for new array");
      exit(EXIT_FAILURE);
  }

  for ( i = 0; i < size; ++i ) {
      new_array[i].myVar = i + 1;
  }   

  *myArray = new_array;
  return size;
}

答案 1 :(得分:2)

代码有点不对劲。在您的代码中,myBigList是指向结构数组的指针。结构的内存已经在数组中(它存储结构而不是指向结构的指针),因此您不需要为每个结构成员分配内存。

当您尝试将指向结构的指针分配给数组成员(这是一个结构,而不是指向结构的指针)时,您的代码应该没有编译,但是由于另一个错误它会成功。请记住,myArray是指向数组的指针,而不是数组本身,因此不是

myArray[i] = aStruct;

你应该写的

(*myArray)[i] = aStruct;

并且编译将失败,因为它应该。要修复代码,请用以下代码替换整个循环:

  for(i = 0; i < size; i++) {
    (*myArray)[i].myVar = i + 1;
  }

并阅读有关指针的更多信息,以了解发生此问题的原因。

正如Paul Griffiths所写,您还需要更改malloc()调用以使用正确的大小。请记住,您希望分配size个数组成员。数组成员的大小是(*myArray)[0]或同等**myArray的大小; *myArray是指向结构的指针的大小,这是不够的。

答案 2 :(得分:1)

内存分配应该如下所示

*myArray = malloc(size * sizeof **myArray);

记住成语

p = malloc(n * sizeof *p);

即。您必须在*下额外增加一个sizeof。如果您的p*myArray,那么在sizeof下,您应该**myArray