我正在调整数组的指针,以避免向后复制数组的所有内容。问题是我想在某个时刻释放数据,除非我将指针移回原来的地址,否则会产生分段错误。有什么方法可以避免这种情况吗?因为如果在函数内执行移位,则调用函数可能不知道移位的大小。
示例:
int i;
float * y = malloc(10*sizeof(float));
for(i=0;i<10;i++) y[i] = (float)i;
y += 2;
for(i=0;i<8;i++) printf("%d\n",y[i]);
free(y); // this will generate a segmentation fault
y -= 2; free(y); // this is OK, but I would like to avoid it
我在这里期待太多了吗?
答案 0 :(得分:4)
这是不可能的。传递给free()
的指针必须从其中一个动态分配函数返回。
从free()
参考页面:
释放先前由malloc(),calloc()或realloc()分配的空间。如果ptr是空指针,则该函数不执行任何操作。
如果ptr与malloc(),calloc()或realloc()之前返回的指针不匹配,则行为未定义。此外,如果ptr引用的内存区域,则行为未定义已经被释放了,也就是说,已经使用ptr作为参数调用了free()或realloc(),并且之后没有调用malloc(),calloc()或realloc()导致指针等于ptr。
因为如果在函数内部执行移位,则调用函数可能不知道移位的大小。
如果指针是通过值传递的,那么对于指针的任何修改都不会对调用者可见,这不是问题:
void f(char* a_ptr) { a_ptr++; }
char* p = malloc(10);
f(p);
free(p); /* Valid as no change was made to 'p'. */
答案 1 :(得分:1)
您可以使用其他变量:
int i;
float * y = malloc(10*sizeof(float));
for(i=0;i<10;i++) y[i] = (float)i;
float *y2 = y+2;
for(i=0;i<8;i++) printf("%d\n",y2[i]);
free(y);
答案 2 :(得分:1)
在malloc之后做float * z = y
,在最后做free(z)
,
答案 3 :(得分:1)
int i;
float *y = malloc(10*sizeof(float));
for(i=0;i<10;i++) y[i] = (float)i;
//y += 2;
float *y2 = y + 2;
for(i=0;i<8;i++) printf("%f\n",y2[i]);
y=realloc(y, 2*sizeof(float));//do free y[2]..y[9]
free(y);//finally