在C中混淆指针

栏目: C · 发布时间: 5年前

内容简介:翻译自:https://stackoverflow.com/questions/2108898/confusing-pointers-in-c

我有一个以上的疑问所以请耐心等待.

有人能告诉我为什么这段代码失败了吗?

#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:我只能想到一个用于创建指针指针的用法(作为实际声明的变量,而不是作为函数参数或由一元&运算符创建的临时变量):a handle .简而言之,句柄是指向指针的指针,其中handl; e由用户拥有,但它指向的指针可以根据需要由OS或库进行更改.

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

事实是,这种策略充其量只是“少吸”.有一大堆缺点:

>一个常见的错误是 程序员 取消引用指针的句柄,并将该指针用于多个函数调用.如果这些函数调用中的任何一个移动了内存,则指针有可能变为无效,并且取消引用它会破坏内存并可能导致程序崩溃.这是一个阴险的错误,因为取消引用坏指针不会导致总线错误或分段错误,因为内存本身仍然存在且可访问;它刚好不再被您使用的对象使用.

>由于这个原因,编译器必须格外小心,并且不能采用一些常见的Subexpression Elimination优化(公共子表达式是对指针的句柄解除引用).

>因此,为了确保正确执行,几乎所有通过句柄的访问都需要两次间接访问,而不是一次使用普通旧指针.这可能会影响性能.

>操作系统或任何库提供的每个API都必须指定它是否可能“移动内存”.如果你调用了其中一个函数,那么通过句柄获得的所有指针现在都是无效的.没有办法让IDE为您执行此操作或检查您,因为移动内存调用和变为无效的指针可能甚至不在同一源文件中.

>性能变得不确定,因为你永远不知道操作系统何时会暂停以压缩你的内存(这涉及很多memcpy()工作).

>多线程变得困难,因为一个线程可以移动内存而另一个线程正在执行或阻塞,使其指针无效.请记住,几乎所有内存分配都必须使用句柄来防止对堆进行分段,因此即使线程不使用任何Mac OS API,线程仍可能需要通过句柄访问内存.

>有函数调用锁定和解锁指针指向的指针,但是,过多的锁定会损害性能并使堆碎片化.

我忘记了可能还有几个.请记住,所有这些缺点仍然比仅使用指针和快速分割堆更加可口,特别是在第一台只有128K RAM的Mac上.这也让我们深入了解为什么Apple完全乐于抛弃所有这些并转向BSD然后他们有机会,一旦他们的整个产品线都有内存管理单元.

翻译自:https://stackoverflow.com/questions/2108898/confusing-pointers-in-c


以上所述就是小编给大家介绍的《在C中混淆指针》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

你不知道的JavaScript(中卷)

你不知道的JavaScript(中卷)

[美] Kyle Simpson / 单业、姜南 / 人民邮电出版社 / 2016-8 / 79.00元

JavaScript这门语言简单易用,很容易上手,但其语言机制复杂微妙,即使是经验丰富的JavaScript开发人员,如果没有认真学习的话也无法真正理解。本套书直面当前JavaScript开发人员不求甚解的大趋势,深入理解语言内部的机制,全面介绍了JavaScript中常被人误解和忽视的重要知识点。本书是其中卷,主要介绍了类型、语法、异步和性能。一起来看看 《你不知道的JavaScript(中卷)》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换