[英]Loss of values in array in struct after function execution
I am working on ac code that holds a structure that hosts some values which I call range. 我正在研究一个AC代码,该代码包含一个结构,该结构包含一些我称为range的值。
My purpose is to use this so called range dynamically (holding different amount of data at every execution). 我的目的是动态使用这个所谓的范围(每次执行时保存不同数量的数据)。 I am now provisionally using the # define comp instead.
我现在暂时使用#define comp代替。 This so called range gets updated every time I call my update_range though the use of s1 structure (and memory allocations).
通过使用s1结构(和内存分配),每次我调用update_range时,这个所谓的range都会更新。
What I found weird is that when I introduced a "show_range" function to output the actual values inside/outside the update function I realized that I loose the first two values. 我发现很奇怪,当我引入“ show_range”函数在更新函数内部/外部输出实际值时,我意识到我松开了前两个值。 Here is the code.
这是代码。 Any suggestions on that?
有什么建议吗? Thanks in advance!
提前致谢!
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <complex.h>
#define comp 1024
// struct holding a complex-valued range
struct range {
int dimensions; /* number of dimensions */
int* size; /* array holding number of points per dimension */
complex double* values; /* array holding complex valued */
int components; /* number of components that will change on any execution*/
};
// parameters to use in function
struct s1 {
int tag;
struct range* range;
};
int update_range(struct s1* arg);
int show_range(struct range* argrange, char* message);
int copy_range(struct range* in, struct range* out);
int main(void) {
int ret = 0;
struct s1 s1;
s1.tag = 0;
s1.range = malloc(sizeof(struct range));
update_range(&s1);
show_range(s1.range, "s1.range inside main function");
return ret;
}
////////////////////////////////////////////
int update_range(struct s1* arg) {
int ret = 0;
int i;
struct range range;
range.dimensions = 1;
range.size = malloc(range.dimensions * sizeof(int));
range.components = comp;
range.size[0] = range.components; // unidimensional case
range.values = malloc(range.components * sizeof(complex double));
for (i = 0; i < range.components; i++) {
range.values[i] = (i + 1) + I * (i + 1);
}
show_range(&range, "range inside update_range function");
arg->range->size =
malloc(range.dimensions * sizeof(int)); // size was unknown before
arg->range->values =
malloc(comp * sizeof(complex double)); // amount of values was unknown
copy_range(&range, arg->range);
show_range(arg->range, "arg->range inside update_range function");
if (range.size)
free(range.size);
range.size = NULL;
if (range.values)
free(range.values);
range.values = NULL;
return ret;
}
////////////////////////////////////////////
// Show parameters (10 first values)
int show_range(struct range* argrange, char* message) {
int ret = 0;
vint i;
printf(" ******************************\n");
printf(" range in %s \n", message);
printf(" arg.dimensions=%d \n", argrange->dimensions);
printf(" arg.size[0]=%d \n", argrange->size[0]);
printf(" argrange.components=%d \n", argrange->components);
printf(" first 10 {Re} values: \n");
for (i = 0; i < 10; i++) {
printf(" argrange.values[%d]=%f\n", i, creal(argrange->values[i]));
}
printf("\n");
return ret;
}
////////////////////////////////////////////
// copy range
int copy_range(struct range* in, struct range* out) {
int ret = 0;
if (in == NULL) {
fprintf(stderr, "error: in points to NULL (%s:%d)\n", __FILE__,
__LINE__);
ret = -1;
goto cleanup;
}
if (out == NULL) {
fprintf(stderr, "error: out points to NULL (%s:%d)\n", __FILE__,
__LINE__);
ret = -1;
goto cleanup;
}
out->dimensions = in->dimensions;
out->size = in->size;
out->values = in->values;
out->components = in->components;
cleanup:
return ret;
}
Your copy_range function is broken, because it copy only pointer to size and values and not the memory. 您的copy_range函数已损坏,因为它仅复制指向大小和值的指针,而不复制内存。 After you call
free(range.size);
调用
free(range.size);
and free(range.values);
和
free(range.values);
you are deleting mamory also from original object but without setting its pointers back to NULL. 您也正在从原始对象删除内存,但没有将其指针设置回NULL。
After calling update_range, s1.range has non NULL pointers in size and values, but they are pointing to deleted memory. 调用update_range之后,s1.range的大小和值均具有非NULL指针,但它们指向已删除的内存。
You are experiencing undefined behaviour (UB) due to accessing freed memory. 由于访问释放的内存,您遇到未定义的行为(UB)。 Your
copy_range()
function only does a shallow copy of the two pointer fields so when you run free(range->size)
you make arg->range->size
invalid. 您的
copy_range()
函数仅对两个指针字段进行浅表复制,因此当您运行free(range->size)
,会使arg->range->size
无效。
You should make copy_range()
a deep copy by allocating and copying the pointer contents like: 您应该通过分配和复制指针内容来使
copy_range()
成为深层副本,例如:
out->size = malloc(in->dimensions * sizeof(int));
memcpy(out->size, in->size, in->dimensions * sizeof(int));
out->values = malloc(in->components * sizeof(complex double));
memcpy(out->values , in->values, in->components * sizeof(complex double));
There are not 10 items to print, so the lines:
printf(" first 10 {Re} values: \n");
for (i = 0; i < 10; i++) {
printf(" argrange.values[%d]=%f\n", i, creal(argrange->values[i]));
}
Will be printing from random memory.
a much better method would be:
printf(" first %d {Re} values: \n", min(argrange.components,10));
for (i = 0; i < argrange.components; i++) {
printf(" argrange.values[%d]=%f\n", i, creal(argrange->values[i]));
}
The above is just one of many problems with the code.
I would suggest executing the code using a debugger to get the full story.
as it is, the code has some massive memory leaks due mostly
to overlaying malloc'd memory pointers.
for instance as in the following:
arg->range->size =
malloc(range.dimensions * sizeof(int)); // size was unknown before
arg->range->values =
malloc(comp * sizeof(complex double)); // amount of values was unknown
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.