C-带结构数组的realloc
我正在做一个结构数组来动态分配一个产品列表,但这只工作了几次(3~5次),然后我得到了这个错误 “./测试”中出现错误:realloc():下一个大小无效:0x00005BC0B44F260* 这是我的代码,这是大学工作的一部分C-带结构数组的realloc,c,C,我正在做一个结构数组来动态分配一个产品列表,但这只工作了几次(3~5次),然后我得到了这个错误 “./测试”中出现错误:realloc():下一个大小无效:0x00005BC0B44F260* 这是我的代码,这是大学工作的一部分 #include <stdio.h> #include <stdlib.h> typedef struct { int cod; float price; } Product; int main () { FILE
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int cod;
float price;
} Product;
int main () {
FILE *fp;
fp = fopen("products.txt", "r+");
if(fp == NULL)
fopen("products.txt", "w+");
int control = 1;
int choice;
int tam = 0;
int i;
Product *p1;
p1 = malloc(sizeof(Product));
while(fread(&p1[0], sizeof(Product), 1, fp) != NULL){
tam++;
}
if(tam > 1){
rewind(fp);
p1 = malloc((tam) * sizeof(*p1));
for (int i = 0; i < tam; i++){
fread(&p1[i], sizeof(Product), 1, fp);
}
}
rewind(fp);
do {
printf("1 - Add product\n2 - Show all products\n3 - Exit\n-> ");
scanf(" %d", &choice);
switch (choice) {
case 1:
if (tam == 0) {
//p1 = malloc(sizeof(Product));
printf("Digit the product code: ");
scanf(" %d", &p1[tam].cod);
printf("Digit the product price: ");
scanf(" %f", &p1[tam].price);
tam++;
} else {
printf("***Realloqing: %d***\n", tam * sizeof(*p1));
p1 = (Product*)realloc(p1, (tam) * sizeof(Product));
for (i = tam; i > 0; i--) {
p1[i].cod = p1[i-1].cod;
p1[i].price = p1[i-1].price;
}
printf("Digit the product code: ");
scanf(" %d", &p1[0].cod);
printf("Digit the product price: ");
scanf(" %f", &p1[0].price);
tam++;
}
break;
case 2:
for (i = 0; i < tam; i++) {
printf("Product code: %d\nProduct price: %f\n", p1[i].cod, p1[i].price);
}
break;
case 3:
control = 0;
break;
}
} while (control);
for (int i = 0; i < tam; i++){
fwrite(&p1[i], sizeof(Product), 1, fp);
}
fclose(fp);
free(p1);
return 0;
}
#包括
#包括
类型定义结构{
国际化学需氧量;
浮动价格;
}产品;
int main(){
文件*fp;
fp=fopen(“products.txt”、“r+”);
如果(fp==NULL)
fopen(“products.txt”、“w+”);
int控制=1;
智力选择;
int-tam=0;
int i;
产品*p1;
p1=malloc(产品尺寸);
while(fread(&p1[0],sizeof(Product),1,fp)!=NULL){
tam++;
}
如果(tam>1){
倒带(fp);
p1=malloc((tam)*sizeof(*p1));
for(int i=0;i”);
scanf(“%d”,选择(&C);
开关(选择){
案例1:
如果(tam==0){
//p1=malloc(产品尺寸);
printf(“产品代码的数字:”);
scanf(“%d”,&p1[tam].cod);
printf(“产品价格的数字:”);
scanf(“%f”、&p1[tam].价格);
tam++;
}否则{
printf(“***Realloqing:%d***\n”,tam*sizeof(*p1));
p1=(产品*)realloc(p1,(tam)*sizeof(产品));
对于(i=tam;i>0;i--){
p1[i].cod=p1[i-1].cod;
p1[i]。价格=p1[i-1]。价格;
}
printf(“产品代码的数字:”);
scanf(“%d”,&p1[0].cod);
printf(“产品价格的数字:”);
scanf(“%f”,&p1[0]。价格);
tam++;
}
打破
案例2:
对于(i=0;i
这是:
p1 = (Product*)realloc(p1, (tam) * sizeof(Product));
违反了Realloc的第一条规则,即不能将Realloc的结果直接分配给作为其第一个参数传递的同一个变量。当您这样做时,如果失败,您就丢失(泄漏)了旧指针
其次,不检查各种函数的返回值,例如malloc()
、realloc()
、和scanf()
。这也是大罪
如果修复了所有仍然导致程序损坏的问题,请使用valgrind。问题在于:
printf("***Realloqing: %d***\n", tam * sizeof(*p1));
p1 = (Product*)realloc(p1, tam * sizeof(Product));
当tam
为1时,则您需要realloctam*sizeof(Product)
,但您需要realloc(tam+1)*sizeof(Product)
,因为现在您需要2产品的空间
因此,这解决了问题:
printf("***Realloqing: %d***\n", (tam + 1) * sizeof(*p1));
p1 = (Product*)realloc(p1, (tam + 1) * sizeof(Product));
有两件事:首先,您不应该将指针分配回传递给
realloc
,如果realloc
失败并返回空指针,您将丢失原始指针并导致内存泄漏。然后你应该阅读。至于你的问题,你写的东西似乎超出了你分配的内存范围。您可能希望使用诸如之类的工具来帮助您发现此类问题。fopen(“products.txt”、“w+”代码>->fp=fopen(“products.txt”、“w+”)
@MichaelWalz感谢我没有看到它tam
是int,而sizeof
产生size\u t
(一种无符号类型)。在做像int*size\t
这样的事情时要小心,你确定“Realloc的第一条规则”吗?声明:如果内存对象的新大小需要移动该对象,则会释放该对象上一次实例化的空间。@KeineLust:是的,我确定。请注意,我说的是“如果失败”。你认为它成功了。我在哪里可以读到更多关于第一条规则等戒律的内容?在这里,它仍然失败。顺便说一句,realloc
,malloc
等。在玩具程序中返回NULL
是不太可能发生的。@anaeath,哦,我刚刚发布了一个答案,但是的,这就是问题所在。