指针最佳实践

4

我刚开始学习C语言,(当然)在指针方面遇到了一些困难 :)

给定以下代码片段:

int *storage, *storage_p;
storage = malloc(sizeof(int[GROW_BY]));
storage_p = storage;
// do something with storage, using storage_p
free(storage);
storage = NULL;

需要声明两个变量才能使用malloc()分配的数据吗?像我这样创建一个storagestorage_p是好的实践吗?如果不是,应该怎么做?


虽然这不是你的问题,但在释放指针或者你知道从这段代码中不再需要它们时,将它们设置为NULL是一个很好的习惯。 - ndim
当两个指针指向相同的内存并且其中一个被释放时,代码是具有危险性的。 - Praveen S
@ndim:我知道,每个关于指针的参考资料都非常清楚地说明了这一点!编辑:我现在明白你的意思了,我也会将storage_p设置为NULL! - Dennis Haarbrink
7个回答

3
你需要一个指针来保存malloc()返回的值,以便稍后释放。
如果你计划使用storage_p来改变它的值,那么你需要两个指针。
然而,我通常保留最初的纯指针,并在需要时即时创建新的指针。
int *storage = (int*) malloc(sizeof(int[GROW_BY])); 
// :
int* ptr = storage;
while (*ptr)
{
  // :
  ++ptr;
}

这正是我的情况。我在循环中使用了 storage(递增它),当我调用 free() 时,我得到了一个段错误。我想我的描述不够清晰。所以,总结一下,通常情况下,除非必须修改指针,否则不会创建副本。这正确吗? - Dennis Haarbrink

2
我只会复制由malloc创建的指针,原因只有一个:我想要修改它。
例如,如果您正在迭代通过malloc分配的字符数组,我会将指针复制到一个新变量中进行迭代,并保留第一个不变。
另外,在动态分配方面,可以看一下空闲列表,它们可以简化很多问题。

http://en.wikipedia.org/wiki/Free_list


1
我建议不要在程序中留有指针的副本。这样只会增加产生未知错误的悬空指针的机会,或者意外使用已被释放的指针等问题。同时也容易出现无需释放的额外副本或重复释放的情况。 在这里,我个人认为没有必要使用“storage_p”。
好的:“Gool 'ol”
int *storage = malloc(size_of_whatever);
storage[0] = do_something();
free(storage);
storage = NULL;

没问题。


1
你可能想这样做的原因是,当你对 storage 进行一些操作后,你可能不记得要释放哪些内存。将 storage_p 作为一个你从未修改过的副本有助于防止内存泄漏,因为无论发生了什么,你都可以稍后调用 free(storage_p)。是否超过已经提到的缺点取决于具体情况的细节。
例如:
int *storage;
storage = malloc(sizeof(int[GROW_BY]));
storage++;
free(storage); //SEGFAULT or MEMORY LEAK or OTHER BAD STUFF
storage = NULL;

对比

int *storage, *storage_p;
storage = malloc(sizeof(int[GROW_BY]));
storage_p = storage;
storage++;
free(storage_p);
storage_p=NULL;
storage = NULL;

1

不,我并没有看出你同时拥有storagestorage_p可以获得什么好处。我通常只会选择其中一个。


0

我觉得这似乎是不必要的。我不确定中间部分可能是什么,但我看不到给指针起别名的任何好处——除非你正在修改 storage_p(例如,递增它以进行迭代)。事实上,有两个别名指针可能会使跟踪已分配内存变得更加困难。


0

没有固有的理由将malloc分配的空间重新分配给另一个指针。

如果这样做,只会不必要地增加代码行数并损害可读性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接