realloc 在 visual studio 中失败,但可以使用 gcc (ntdll.dll)
realloc fails in visual studio, but work using gcc (ntdll.dll)
我正在使用 Visual Studio 2017,我在 C 中有这段代码。当我在 VS 中 运行 时它失败了,但是当我用 gcc 编译时它 运行 完美。错误是这样的:
Exception thrown at 0x779BE643 (ntdll.dll) in GestaoFinanceira.exe: 0xC0000005: Access violation reading location 0x00000009.
这是我的代码。
我正在使用这种结构类型:
struct budget {
struct tm time;
float valor;
};
struct geral {
struct budget *b;
int nelem_budget;
};
在 main 中,我调用了一个函数,该函数将从文件中读取并将值保存为结构 g->b[]
作为 g->nelem_budget
中的元素数
int main() {
struct geral *g = (struct geral *)malloc(sizeof(struct geral));
readFileBudget(g);
// just to check if the read was ok
showBudget(g->b, g->nelem_budget);
addBudget(g);
// to check again if the item added is ok
showBudget(g->b, g->nelem_budget);
system("Pause");
return 0;
}
这是错误出现的时间:
void addBudget(struct geral *g) {
int month, year;
float value;
// in the future, this values are to be an user input
month = 5;
year = 2015;
value = 5000;
printf("Month: %d, Year: %d, Value: %f\n", month, year, value);
g->b[g->nelem_budget].time.tm_mon = month;
g->b[g->nelem_budget].time.tm_year = year;
g->b[g->nelem_budget].valor = value;
g->nelem_budget++;
struct budget *tmp = NULL;
tmp = g->b;
g->b = realloc(g->b, g->nelem_budget * sizeof(struct budget));
if (g->b == NULL) { //reallocated pointer ptr1
free(tmp);
printf("error-addBudget->realloc");
exit(EXIT_FAILURE);
}
// just for debug
printf("month: %d, year: %d, value: %f\n", g->b[g->nelem_budget - 1].time.tm_mon, g->b[g->nelem_budget - 1].time.tm_year, g->b[g->nelem_budget - 1].valor);
}
我在 g->b
数组的末尾有一个空值,这就是我首先添加值,然后调用 realloc
.
的原因
你需要先重新分配,然后再添加一个新元素,而不是相反。
我不喜欢这个
struct budget *tmp = NULL;
tmp = g->b;
g->b = realloc(g->b, g->nelem_budget * sizeof(struct budget));
if (g->b == NULL) { //reallocated pointer ptr1
free(tmp);
printf("error-addBudget->realloc");
exit(EXIT_FAILURE);
}
出于几个原因:
realloc
应该这样称呼:
struct budget *tmp;
tmp = realloc(g->b, (g->nelem_budget + 1) * sizeof *tmp);
if(tmp == NULL)
{
// error handling
return 0; // return error code
}
g->b = tmp;
g->nelem_budget++;
不要在 main
以外的函数中执行 exit
。而不是关闭程序,
使 addBudget
return 成功时为 1,失败时为 0。 addBudget
的来电者
应该决定在失败的情况下该怎么做,而不是 addBudget
。例如,如果你
把这些函数放在一个库中,你的程序会在出错时自动结束,
而这有时是您不希望发生的事情。
所以,函数应该是这样的:
int addBudget(struct geral *g) {
if(g == NULL)
return 0;
int month, year;
float value;
// in the future, this values are to be an user input
month = 5;
year = 2015;
value = 5000;
// reallocate first
struct budget *tmp = NULL;
tmp = realloc(g->b, (g->nelem_budget + 1) * sizeof *tmp);
if(tmp == NULL)
{
fprintf(stderr, "error-addBudget->realloc\n");
return 0;
}
g->b = tmp;
// add new budget after reallocation
printf("Month: %d, Year: %d, Value: %f\n", month, year, value);
g->b[g->nelem_budget].time.tm_mon = month;
g->b[g->nelem_budget].time.tm_year = year;
g->b[g->nelem_budget].valor = value;
g->nelem_budget++;
// just for debug
printf("month: %d, year: %d, value: %f\n", g->b[g->nelem_budget - 1].time.tm_mon, g->b[g->nelem_budget - 1].time.tm_year, g->b[g->nelem_budget - 1].valor);
return 1;
}
然后在 main
:
int main() {
// using calloc to initialize
// everything with 0
struct geral *g = calloc(1, sizeof *g);
if(g == NULL)
{
fprintf(stderr, "Not engough memory\n");
return 1;
}
// you should also check of readFileBudget
// fails
readFileBudget(g);
// just to check if the read was ok
showBudget(g->b, g->nelem_budget);
if(addBudget(g) == 0)
{
free(g->b);
free(g);
return 1;
}
// to check again if the item added is ok
showBudget(g->b, g->nelem_budget);
// don't forget to free the memory
free(g->b);
free(g);
system("Pause");
return 0;
}
另见:do not cast malloc
并且错误消息应该打印到 stderr
,而不是 stdout
。
我正在使用 Visual Studio 2017,我在 C 中有这段代码。当我在 VS 中 运行 时它失败了,但是当我用 gcc 编译时它 运行 完美。错误是这样的:
Exception thrown at 0x779BE643 (ntdll.dll) in GestaoFinanceira.exe: 0xC0000005: Access violation reading location 0x00000009.
这是我的代码。
我正在使用这种结构类型:
struct budget {
struct tm time;
float valor;
};
struct geral {
struct budget *b;
int nelem_budget;
};
在 main 中,我调用了一个函数,该函数将从文件中读取并将值保存为结构 g->b[]
作为 g->nelem_budget
int main() {
struct geral *g = (struct geral *)malloc(sizeof(struct geral));
readFileBudget(g);
// just to check if the read was ok
showBudget(g->b, g->nelem_budget);
addBudget(g);
// to check again if the item added is ok
showBudget(g->b, g->nelem_budget);
system("Pause");
return 0;
}
这是错误出现的时间:
void addBudget(struct geral *g) {
int month, year;
float value;
// in the future, this values are to be an user input
month = 5;
year = 2015;
value = 5000;
printf("Month: %d, Year: %d, Value: %f\n", month, year, value);
g->b[g->nelem_budget].time.tm_mon = month;
g->b[g->nelem_budget].time.tm_year = year;
g->b[g->nelem_budget].valor = value;
g->nelem_budget++;
struct budget *tmp = NULL;
tmp = g->b;
g->b = realloc(g->b, g->nelem_budget * sizeof(struct budget));
if (g->b == NULL) { //reallocated pointer ptr1
free(tmp);
printf("error-addBudget->realloc");
exit(EXIT_FAILURE);
}
// just for debug
printf("month: %d, year: %d, value: %f\n", g->b[g->nelem_budget - 1].time.tm_mon, g->b[g->nelem_budget - 1].time.tm_year, g->b[g->nelem_budget - 1].valor);
}
我在 g->b
数组的末尾有一个空值,这就是我首先添加值,然后调用 realloc
.
你需要先重新分配,然后再添加一个新元素,而不是相反。
我不喜欢这个
struct budget *tmp = NULL;
tmp = g->b;
g->b = realloc(g->b, g->nelem_budget * sizeof(struct budget));
if (g->b == NULL) { //reallocated pointer ptr1
free(tmp);
printf("error-addBudget->realloc");
exit(EXIT_FAILURE);
}
出于几个原因:
realloc
应该这样称呼:
struct budget *tmp;
tmp = realloc(g->b, (g->nelem_budget + 1) * sizeof *tmp);
if(tmp == NULL)
{
// error handling
return 0; // return error code
}
g->b = tmp;
g->nelem_budget++;
不要在 main
以外的函数中执行 exit
。而不是关闭程序,
使 addBudget
return 成功时为 1,失败时为 0。 addBudget
的来电者
应该决定在失败的情况下该怎么做,而不是 addBudget
。例如,如果你
把这些函数放在一个库中,你的程序会在出错时自动结束,
而这有时是您不希望发生的事情。
所以,函数应该是这样的:
int addBudget(struct geral *g) {
if(g == NULL)
return 0;
int month, year;
float value;
// in the future, this values are to be an user input
month = 5;
year = 2015;
value = 5000;
// reallocate first
struct budget *tmp = NULL;
tmp = realloc(g->b, (g->nelem_budget + 1) * sizeof *tmp);
if(tmp == NULL)
{
fprintf(stderr, "error-addBudget->realloc\n");
return 0;
}
g->b = tmp;
// add new budget after reallocation
printf("Month: %d, Year: %d, Value: %f\n", month, year, value);
g->b[g->nelem_budget].time.tm_mon = month;
g->b[g->nelem_budget].time.tm_year = year;
g->b[g->nelem_budget].valor = value;
g->nelem_budget++;
// just for debug
printf("month: %d, year: %d, value: %f\n", g->b[g->nelem_budget - 1].time.tm_mon, g->b[g->nelem_budget - 1].time.tm_year, g->b[g->nelem_budget - 1].valor);
return 1;
}
然后在 main
:
int main() {
// using calloc to initialize
// everything with 0
struct geral *g = calloc(1, sizeof *g);
if(g == NULL)
{
fprintf(stderr, "Not engough memory\n");
return 1;
}
// you should also check of readFileBudget
// fails
readFileBudget(g);
// just to check if the read was ok
showBudget(g->b, g->nelem_budget);
if(addBudget(g) == 0)
{
free(g->b);
free(g);
return 1;
}
// to check again if the item added is ok
showBudget(g->b, g->nelem_budget);
// don't forget to free the memory
free(g->b);
free(g);
system("Pause");
return 0;
}
另见:do not cast malloc
并且错误消息应该打印到 stderr
,而不是 stdout
。