如何在运行时动态增加任何结构对象的大小?
How to dynamically increase size of any structure objects during runtime?
我是C语言的初学者。我正在尝试在输入通过时动态重新分配内存的任务(尽管对于这个测试我正在做一个正常的任务,稍后会尝试扩大它)。我面临的问题是我在写入内存时无法访问内存。任何人都可以帮助我理解我在这段代码中出错的地方。提前致谢。
代码:
#include<stdio.h>
#include<stdlib.h>
struct ai {
int* a;
char* b;
};
int main()
{
struct ai *test;
test = (struct ai*) malloc(sizeof(struct ai));
test[0].a = (int*)malloc(sizeof(int));
test[0].b = (char*)malloc(sizeof(char));
/// storing info
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
test[i].a[j] = j;
test[i].b[j] = 65 + j;
test[i].a = (int *) realloc(test[i].a, (j + 2) * sizeof(int));
test[i].b = (char*) realloc(test[i].b, (j + 2) * sizeof(char));
}
test = (struct ai*)realloc(test, (i + 2) * sizeof(struct ai));
}
// printing the block out
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d , %c\n", test[i].a[j], test[i].b[j]);
}
}
return 0;
} ```
您缺少指针初始化和其他一些问题...
int main()
{
struct ai *test;
test = (struct ai*) malloc(sizeof(struct ai));
test[0].a = (int*)malloc(sizeof(int));
test[0].b = (char*)malloc(sizeof(char));
在 C 中你不应该转换 malloc
的结果。在最好的情况下它是无用的。在最坏的情况下,它隐藏了真正的问题。
/// storing info
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
test[i].a[j] = j;
test[i].b[j] = 65 + j;
这是您的分段错误的原因:
除了第一个元素 test[0]
之外,您没有为 a
和 b
保留任何内存。所有其他数组元素 test[i]
不包含任何有用的数据。取消引用这些指针是未定义的行为。
扩大数组后必须为每个字段分配内存。
test[i].a = (int *) realloc(test[i].a, (j + 2) * sizeof(int));
test[i].b = (char*) realloc(test[i].b, (j + 2) * sizeof(char));
您永远不应将 realloc
的 return 值分配给您传递给函数的同一个变量。如果出现错误,您将获得 NULL
return 值,然后您的初始指针将丢失。
同样在这里:也不要为 realloc
投射。
}
test = (struct ai*)realloc(test, (i + 2) * sizeof(struct ai));
这里相同:不要分配给同一个变量,也不要转换 realloc
的结果。
最后:这是遗漏的部分:
test[i+1].a = malloc(sizeof(*test[0].a));
test[i+1].b = malloc(sizeof(*test[0].b));
}
当然,您应该检查所有 return 值的错误结果。
与分段错误无关,但仍值得修复:
在使用完最后一个元素后增加每个数组的大小。
这为在循环的下一次迭代中填充新元素做好了准备。但是在最后一次迭代的情况下,它为内部指针 a
和 b
以及外部数组 test
.
分配了一个未使用的元素
您将有一些未使用的元素:
test[0].a[4]
test[0].b[4]
test[1].a[4]
test[1].b[4]
test[2].a[0]
test[2].b[0]
改进的解决方案可能如下所示(未测试)
我从每个指针开始 NULL
并在使用新元素之前使用 realloc
以避免额外的元素。
int main(void)
{
struct ai *test = NULL
void *tmp;
// storing info
for (int i = 0; i < 2; i++)
{
tmp = realloc(test, (i+1) * sizeof(*test))
if (tmp == NULL)
exit(1);
test = tmp;
test[i].a = NULL;
test[i].b = NULL;
for (int j = 0; j < 4; j++)
{
tmp = realloc(test[i].a, (j+1) * sizeof(test[i].a[0]));
if (tmp == NULL)
exit(1);
test[i].a = tmp;
tmp = realloc(test[i].b, (j+1) * sizeof(test[i].b[0]));
if (tmp == NULL)
exit(1);
test[i].b = tmp;
test[i].a[j] = j;
test[i].b[j] = 65 + j;
}
}
// printing the block out
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d , %c\n", test[i].a[j], test[i].b[j]);
}
}
return 0;
}
我是C语言的初学者。我正在尝试在输入通过时动态重新分配内存的任务(尽管对于这个测试我正在做一个正常的任务,稍后会尝试扩大它)。我面临的问题是我在写入内存时无法访问内存。任何人都可以帮助我理解我在这段代码中出错的地方。提前致谢。
代码:
#include<stdio.h>
#include<stdlib.h>
struct ai {
int* a;
char* b;
};
int main()
{
struct ai *test;
test = (struct ai*) malloc(sizeof(struct ai));
test[0].a = (int*)malloc(sizeof(int));
test[0].b = (char*)malloc(sizeof(char));
/// storing info
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
test[i].a[j] = j;
test[i].b[j] = 65 + j;
test[i].a = (int *) realloc(test[i].a, (j + 2) * sizeof(int));
test[i].b = (char*) realloc(test[i].b, (j + 2) * sizeof(char));
}
test = (struct ai*)realloc(test, (i + 2) * sizeof(struct ai));
}
// printing the block out
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d , %c\n", test[i].a[j], test[i].b[j]);
}
}
return 0;
} ```
您缺少指针初始化和其他一些问题...
int main()
{
struct ai *test;
test = (struct ai*) malloc(sizeof(struct ai));
test[0].a = (int*)malloc(sizeof(int));
test[0].b = (char*)malloc(sizeof(char));
在 C 中你不应该转换 malloc
的结果。在最好的情况下它是无用的。在最坏的情况下,它隐藏了真正的问题。
/// storing info
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
test[i].a[j] = j;
test[i].b[j] = 65 + j;
这是您的分段错误的原因:
除了第一个元素 test[0]
之外,您没有为 a
和 b
保留任何内存。所有其他数组元素 test[i]
不包含任何有用的数据。取消引用这些指针是未定义的行为。
扩大数组后必须为每个字段分配内存。
test[i].a = (int *) realloc(test[i].a, (j + 2) * sizeof(int));
test[i].b = (char*) realloc(test[i].b, (j + 2) * sizeof(char));
您永远不应将 realloc
的 return 值分配给您传递给函数的同一个变量。如果出现错误,您将获得 NULL
return 值,然后您的初始指针将丢失。
同样在这里:也不要为 realloc
投射。
}
test = (struct ai*)realloc(test, (i + 2) * sizeof(struct ai));
这里相同:不要分配给同一个变量,也不要转换 realloc
的结果。
最后:这是遗漏的部分:
test[i+1].a = malloc(sizeof(*test[0].a));
test[i+1].b = malloc(sizeof(*test[0].b));
}
当然,您应该检查所有 return 值的错误结果。
与分段错误无关,但仍值得修复:
在使用完最后一个元素后增加每个数组的大小。
这为在循环的下一次迭代中填充新元素做好了准备。但是在最后一次迭代的情况下,它为内部指针 a
和 b
以及外部数组 test
.
您将有一些未使用的元素:
test[0].a[4]
test[0].b[4]
test[1].a[4]
test[1].b[4]
test[2].a[0]
test[2].b[0]
改进的解决方案可能如下所示(未测试)
我从每个指针开始 NULL
并在使用新元素之前使用 realloc
以避免额外的元素。
int main(void)
{
struct ai *test = NULL
void *tmp;
// storing info
for (int i = 0; i < 2; i++)
{
tmp = realloc(test, (i+1) * sizeof(*test))
if (tmp == NULL)
exit(1);
test = tmp;
test[i].a = NULL;
test[i].b = NULL;
for (int j = 0; j < 4; j++)
{
tmp = realloc(test[i].a, (j+1) * sizeof(test[i].a[0]));
if (tmp == NULL)
exit(1);
test[i].a = tmp;
tmp = realloc(test[i].b, (j+1) * sizeof(test[i].b[0]));
if (tmp == NULL)
exit(1);
test[i].b = tmp;
test[i].a[j] = j;
test[i].b[j] = 65 + j;
}
}
// printing the block out
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d , %c\n", test[i].a[j], test[i].b[j]);
}
}
return 0;
}