C 中令人困惑的指针

2024-03-02

我有不止一个疑问,所以请耐心等待。 有人能告诉我为什么这段代码失败吗?

#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[] and char **list两者都适合在什么情况下使用? 另一件让我困惑的事情是 argv 很特别吗?当我经过时char **list到另一个函数,假设它可以让我以我可以的方式访问内容argv,也失败了。

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


你应该使用char *list[]={"aaa","bbb","ccc"};代替char **list={"aaa","bbb","ccc"};。你用char* list[] = {...}; to declare指针数组,但你使用char**将一个指针传递给一个或多个指向函数的指针。

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

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

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

事实是,这种策略充其量只是“吸得更少”。有很多缺点:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 中令人困惑的指针 的相关文章

随机推荐

  • ggplot:如何用箭头连接图表中的某些条形

    目前我正在复制 更新海报演示的某些图形 我成功地复制了图形的颜色 值 条形样式和背景 但是缺少一个箭头标签 突出显示了值差异 我想知道是否有通过 ggplot 线条或箭头 的有用选项 值得付出努力 或者我必须用另一个图形软件绘制一些箭头 这
  • 到凸包的距离

    我一直在寻找一种方法来计算到凸包 多边形的距离 如果该点在包内 则距离为正 如果在包外 则距离为负 例如 给定一个船体和一组点 可以计算正 负距离吗 from scipy spatial import ConvexHull import m
  • 如何将 Solr 索引转储/备份到文件?

    我正在运行一个虚拟专用服务器 每天午夜 所有文件都会自动备份由 VPS 提供商提供 所以我需要exportSolr 索引到文件 这样如果有一天出现问题 我将能够import它轻松返回到 Solr 我怎样才能做到这一点 Solr 数据库是一个
  • 使用 QLabel 在 PyQt GUI 中显示 gif

    我试图在按下按钮后显示加载 gif 这是我目前拥有的代码 import sys from PyQt4 import QtGui QtCore from PyQt4 QtCore import from PyQt4 QtGui import
  • 子进程 check_output 返回非零退出状态 1

    这是我的Python代码 import subprocess subprocess check output ls shell True stderr subprocess STDOUT import subprocess subproce
  • 如何知道文字的方向?

    在 UITextView 中输入时 我需要根据键盘的语言了解文本的方向 例如 如果用户输入英语 则方向将为 从左到右 如果用户输入阿拉伯语 则方向将为 从右到左 我毫无疑问地需要这个值 并避免对每种语言及其文本方向之间的匹配进行硬编码 这可
  • LESSCHARSET=utf-8 less 似乎不起作用

    我正在尝试查看 UTF 8 文本文件 流less 即使我像这样调用它 cat file LESSCHARSET utf 8 less 非 ASCII 兼容的 UTF 8 字符无法正确显示 相反 它们的十六进制值在括号中突出显示 例如
  • Java 构建路径 - 添加外部 JAR 并添加变量

    Java 构建路径 添加外部 JAR 按钮和添加变量按钮功能之间有什么区别 为什么需要它 请详细解释一下 两者都可以用来实现相同的目标 将 JAR 添加到构建路径中 假设您有一个项目 P1 想要使用供应商 S1 安装的 JAR 该 JAR
  • Java 8 过滤器映射 >

    如何过滤一个Map
  • iPhone 上的 CoreMotion 碰撞与震动

    我正在尝试检测用户何时将 iPhone 撞到另一个物体上 以及何时只是摇晃手机 我似乎无法让它按照我想要的方式完美工作 因为它要么记录太多颠簸 要么没有颠簸 或者认为摇晃就是颠簸 有人可以看看我下面的代码并提供建议吗 我需要确保其中之一发生
  • 当由 router-outlet 创建组件时,如何为组件设置输入绑定?

    当路由器创建组件时 如何设置属性绑定 不支持对路由器添加的组件使用绑定 另请参阅此讨论https github com angular angular issues 4452 https github com angular angular
  • TypeORM:PostgreSQL 中自动生成的 UUID

    我正在编写一个 REST API 对于数据访问 我正在使用 typeorm 我已经成功使用了它 但我希望在我的一个表上有一个 UUID 自动生成的主键 有谁知道如何在 typeorm 中设置 UUID 类型并自动生成的列 我尝试了以下操作
  • 安卓。内存不足问题

    我需要在我的应用程序中显示许多图像 这些是 jpg 和 png 我将它们加载到 ImageView 中 如下所示 tile setImageResource R drawable tile highlight 我目前遇到内存不足问题 jav
  • 追加后访问元素

    我需要在 JQuery 追加后访问 DOM 元素 假设我有这个 ul li class item one li li class item two li ul 然后是 JavaScript var addItems function htm
  • 当 .CSV 的值之一可能在字符串中包含逗号时处理 .CSV

    我有一个 csv 需要将其转换为 Coldfusion 查询 我使用了 cflib org CSVtoQuery 方法 效果很好 但是 如果 csv 中有一个 单元格 在字符串中包含逗号 例如列表 则该记录的查询行会变得混乱 因为它将字符串
  • 使用 Intersection Observer API 延迟翻译元素

    我在用着路口观察器 API https developer mozilla org en US docs Web API Intersection Observer API当用户滚动到内容时显示元素 效果很好 但我想要延迟显示 div 如果
  • Swagger - 授权对带有文档的 url 的请求

    我想知道 Swagger 中是否有一个选项可以授权对包含外部文档的 url 的请求 我有以下配置 我感兴趣的是urls 1 part springdoc swagger ui urls 0 url v3 api docs springdoc
  • 将 PIL 图像保存为 json 的最佳方法是什么

    我正在尝试发送应包含 Pillow 图像作为其字段之一的 json 字典 为此我必须将图像转换为字符串 我尝试使用枕头功能 image toString 但仍然以字节的形式得到它 所以我尝试对其进行编码 buff BytesIO image
  • 将 matplotlib 图像发送到 pymsteams(无法创建新标签 pymsteams)

    我正在使用 matplotlib 来绘制我的图像 import pandas as pd from matplotlib import pyplot as plt x 09 30 09 33 09 40 09 43 09 50 09 53
  • C 中令人困惑的指针

    我有不止一个疑问 所以请耐心等待 有人能告诉我为什么这段代码失败吗 include