【问题标题】:Why does realloc not update the size of my array?为什么 realloc 不更新我的数组的大小?
【发布时间】:2016-09-12 17:28:33
【问题描述】:

我正在尝试读取用户输入,然后使用 strtok() 将其解析为令牌。 这是我的代码:

int main(){
char argv[200];
char** tokenList = NULL;

printf("shell>>");
scanf("%[^\n]%*c", argv);
int len = 0;
char* line = strtok(argv, " ");
while (line != NULL) {
   printf("%s\n", line);
   printf("%lu\n", sizeof(tokenList) + (sizeof(char*) * (len+1)));
   tokenList = realloc(tokenList, sizeof(tokenList) + (sizeof(char*) * (len+1)));
   printf("%lu\n", sizeof(tokenList));
   char* p = malloc(sizeof(char) * (sizeof(line) + 1));
   p=line;
   tokenList[len] = p;
   len++;
   line = strtok(NULL, " ");
  }

三个打印语句用于我的调试目的,我无法弄清楚发生了什么。当我运行 shell 并输入“a b c”时,我的输出如下:

a
16
8
b
24
8
c
32
8

为什么我的数组 tokenList 的大小没有被 realloc 调用更新?

【问题讨论】:

  • 指针不是数组!无论如何,这不是 C 的工作方式。 C 中没有动态长度的数组。所有类型都是静态声明的。 realloc 只是改变内存块的大小(就像malloc 分配它)。
  • sizeof() 仅在编译期间有效,在运行时无效。它确定给定对象/变量的大小,而不是它指向的任何内容。
  • @Olaf:“C 中没有动态长度的数组。”当然有 VLA(可变长度数组),但是每个 VLA 对象的大小在创建时在运行时是固定的。这个小问题与 OP 的问题无关。
  • @KeithThompson:我很确定你知道我知道 VLA :-)。是的,我的评论具有误导性。一旦定义,VLA就不能改变长度(我不应该使用declared)。动态数组可以更改大小并跟踪该更改。如果需要,对于一维数组,具有灵活数组成员的struct 将是一种好方法。但是没有隐含的长度信息。
  • @Olaf:同意。只要我们在狡辩,“静态”通常是一个合理的术语,用于表示恒定的东西,但是 C 使用“静态”这个词来指代一种存储分配,这在这种情况下是不可取的。可以创建具有自动或静态存储持续时间的命名数组对象;无论哪种情况,它的大小在创建时都是固定的。 (我毫不怀疑你知道这一切。)

标签: c arrays memory malloc realloc


【解决方案1】:

您在指针上使用sizeof 运算符。这会产生 指针 的字节大小,而不是指向的数据长度。不难想象,为什么tokenList 只是一个存储地址的变量,你得到的是变量的大小,而不是变量指向的内容。

在 C 中,分配在堆上的数组不知道它们的大小,开发人员必须注意知道它并在需要时在某处存储/更新它。

您可以直接使用sizeof 的唯一情况是使用静态或本地存储(而不是在堆上)声明数组时。在这种情况下sizeof返回数组的总长度,以便您可以通过sizeof(array) / sizeof(array[0])获取元素个数。

【讨论】:

  • 杰克,这不是“例外”。它只是计算传递的对象/变量的字节大小。
猜你喜欢
  • 1970-01-01
  • 2014-07-02
  • 2021-10-14
  • 2019-10-26
  • 2012-10-01
  • 1970-01-01
  • 2016-04-20
  • 1970-01-01
  • 2017-08-24
相关资源
最近更新 更多