gpt4 book ai didi

C中令人困惑的指针

转载 作者:太空狗 更新时间:2023-10-29 17:05:52 25 4
gpt4 key购买 nike

我有不止一个疑问,所以请多多包涵。谁能告诉我为什么这段代码会失败?

#include<stdio.h>
void main(int argc,char **argv) /*assume program called with arguments aaa bbb ccc*/
{
char **list={"aaa","bbb","ccc"};

printf("%s",argv[1]);/*prints aaa*/
printf("%s",list[1]); /*fails*/
}

我认为它与指向指针的指针有关,我不太清楚。所以我尝试了:

#include<stdio.h>
void main()
{
char **list={"aaa","bbb","ccc"};
char *ptr;
ptr=list;
printf("%s",ptr);/*this prints the first string aaa*/
/* My second question is how do i increment the value
of ptr so that it points to the second string bbb*/
}

char *list[]char **list 有什么区别,在什么情况下最适合使用?让我困惑的另一件事是 argv 特别?当我将 char **list 传递给另一个函数时,假设它会让我以使用 argv 的方式访问内容,它也失败了。

我意识到过去有人问过类似的问题,但我似乎找不到我需要的东西。如果可以,有人可以发布相关链接。

最佳答案

你应该使用 char *list[]={"aaa","bbb","ccc"}; 而不是 char **list={"aaa","bbb ","ccc"};。您使用 char* list[] = {...};声明指针数组,但您使用 char** 来传递指向函数的一个或多个指针的指针。

  • T* x[] = 指针数组
  • T** x = 指向指针的指针

附言回应 ejohn:我能想到的只有一种用途是创建指向指针的指针(作为实际声明的变量,而不是作为函数参数或由一元 & 运算符创建的临时变量):一个handle .简而言之,句柄是指向指针的指针,其中句柄归用户所有,但它指向的指针可以根据操作系统或库的需要进行更改。

句柄在旧的 Mac OS 中被广泛使用。由于 Mac OS 是在没有虚拟内存技术的情况下开发的,因此防止堆快速碎片化的唯一方法是在几乎所有内存分配中都使用句柄​​。这让操作系统可以根据需要移动内存以压缩堆并打开更大、连续的空闲内存块。

事实是,这种策略充其量只是“收效甚微”。有很多缺点:

  • 一个常见的错误是程序员取消对指针句柄的引用,并将该指针用于多个函数调用。如果这些函数调用中的任何一个移动了内存,指针就有可能变得无效,并且取消引用它会破坏内存并可能使程序崩溃。这是一个隐蔽的错误,因为取消引用坏指针不会导致总线错误或段错误,因为内存本身仍然存在并且可以访问;它只是不再被您使用的对象使用。
  • 出于这个原因,编译器必须格外小心,并且无法采用一些公共(public)子表达式消除优化(公共(public)子表达式是对指针的句柄取消引用)。
  • 因此,为了确保正确执行,几乎所有通过句柄的访问都需要两次间接访问,而不是一次使用普通指针的访问。这可能会影响性能。
  • 操作系统或任何库提供的每个 API 都必须指定它是否可能“移动内存”。如果您调用其中一个函数,您通过句柄获得的所有指针现在都无效。没有办法让 IDE 为您执行此操作或检查您,因为移动内存调用和变得无效的指针甚至可能不在同一个源文件中。
  • 性能变得不确定,因为您永远不知道操作系统何时暂停以压缩您的内存(这涉及 很多 memcpy() 工作)。
  • 多线程变得困难,因为一个线程可能会在另一个线程正在执行或阻塞时移动内存,从而使其指针无效。请记住,几乎所有内存分配都必须使用句柄以避免堆碎片化,因此线程仍然可能需要通过句柄访问内存,即使它们不使用任何 Mac OS API。
  • 有用于锁定和解锁句柄指向的指针的函数调用,但是,过多的锁定会损害性能并使堆碎片化。

可能还有几个我忘记了。请记住,所有这些缺点仍然比仅使用指针和快速分割堆更容易接受,尤其是在只有 128K RAM 的第一台 Mac 上。这也让我们可以深入了解为什么 Apple 非常乐意放弃所有这些并转向 BSD,然后他们有机会,一旦他们的整个产品线都有内存管理单元。

关于C中令人困惑的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2108898/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com