相关疑难解决方法(0)

为什么地址零用于空指针?

在C(或C++)中,指针是特殊的,如果它们的值为零:我建议在释放内存后将指针设置为零,因为这意味着再次释放指针并不危险; 当我调用malloc时,如果它无法获取内存,则返回一个值为零的指针; 我一直用if (p != 0)它来确保传递的指针是有效的,等等.

但是,由于内存寻址从0开始,因此有效地址不是0吗?如果是这样的话,0如何用于处理空指针?为什么不是负数而是null?


编辑:

一堆好的答案.我将总结在所表达的答案中所说的内容,因为我自己的思想解释了它,并希望如果我误解,社区将纠正我.

  • 就像编程中的其他一切一样,它是一种抽象.只是一个常量,与地址0并不真正相关.C++ 0x通过添加关键字来强调这一点nullptr.

  • 它甚至不是地址抽象,它是C标准指定的常量,只要它确保它永远不等于"真实"地址,编译器就可以将它转换为其他数字,如果0不是,则等于其他空指针用于平台的最佳价值.

  • 如果它不是抽象,早期就是这种情况,系统使用地址0,程序员不受限制.

  • 我承认,我的负面数字建议是一个狂热的头脑风暴.对地址使用有符号整数有点浪费,如果它意味着除了空指针(-1或其他)之外,值空间在产生有效地址的正整数和刚刚浪费的负数之间均匀分配.

  • 如果任何数字总是可以由数据类型表示,那么它就是0.(也可能是1.我想的是一位整数,如果是无符号则为0或1,或者只有符号的有符号位,或两位整数,将是[-2,1].但是你可以只得0为空,1是内存中唯一可访问的字节.)

还有一些东西在我的脑海里没有得到解决.Stack Overflow问题指向特定固定地址的指针告诉我,即使0表示空指针是抽象,其他指针值也不一定.这导致我发布另一个Stack Overflow问题,我是否可以访问地址零?.

c c++ memory pointers

119
推荐指数
6
解决办法
3万
查看次数

重新定义NULL

我正在为地址0x0000有效且包含端口I/O的系统编写C代码.因此,访问NULL指针的任何可能的错误都将保持不被检测到,同时会导致危险的行为.

出于这个原因,我希望将NULL重新定义为另一个地址,例如一个无效的地址.如果我不小心访问了这样的地址,我将得到一个硬件中断,我可以处理错误.我碰巧有权访问此编译器的stddef.h,因此我实际上可以更改标准头并重新定义NULL.

我的问题是:这会与C标准发生冲突吗?据我所知,从标准中的7.17开始,宏是实现定义的.标准中的其他地方是否有任何内容表明NULL 必须为0?

另一个问题是,无论数据类型如何,大量编译器都会通过将所有内容设置为零来执行静态初始化.尽管标准规定编译器应将整数设置为零并将指针设置为NULL.如果我将为我的编译器重新定义NULL,那么我知道这样的静态初始化将失败.我是否可以将其视为不正确的编译器行为,即使我手动大胆地更改了编译器头?因为我确实知道这个特定的编译器在进行静态初始化时不访问NULL宏.

c null

118
推荐指数
4
解决办法
4558
查看次数

是否可以将C指针初始化为NULL?

我一直在写类似的东西

char *x=NULL;
Run Code Online (Sandbox Code Playgroud)

假设是

 char *x=2;
Run Code Online (Sandbox Code Playgroud)

会创建一个char指向地址2 的指针.

但是,在GNU C编程教程中,它表示int *my_int_ptr = 2;将整数值存储2my_int_ptr分配时的任何随机地址.

这似乎意味着我自己char *x=NULL正在将NULL一个cast 的值分配给char内存中的某个随机地址.

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char *x=NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

事实上,印刷品

一片空白

当我编译并运行它时,我担心我依赖于未定义的行为,或者至少是指定不足的行为,我应该写

char *x;
x=NULL;
Run Code Online (Sandbox Code Playgroud)

代替.

c pointers initialization

88
推荐指数
6
解决办法
3万
查看次数

C硬编码数组作为memcpy参数

我想传入一个硬编码的char数组作为sourcememcpy 的参数...像这样:

memcpy(dest, {0xE3,0x83,0xA2,0xA4,0xCB} ,5);
Run Code Online (Sandbox Code Playgroud)

使用clang编译时会出现以下错误:

cccc.c:28:14: error: expected expression
Run Code Online (Sandbox Code Playgroud)

如果我修改它(参见额外的括号):

memcpy(dest,({0xAB,0x13,0xF9,0x93,0xB5}),5);
Run Code Online (Sandbox Code Playgroud)

clang给出的错误是:

cccc.c:26:14: warning: incompatible integer to pointer
              conversion passing 'int' to parameter of
              type 'const void *' [-Wint-conversion]

cccc.c:28:40: error: expected ';' after expression
memcpy(c+110,({0xAB,0x13,0xF9,0x93,0xB5}),5);
Run Code Online (Sandbox Code Playgroud)

那么,问题是:

如何传入硬编码数组作为memcpy(http://www.cplusplus.com/reference/cstring/memcpy/)的源参数

我试过了:

(void*)(&{0xAB,0x13,0xF9,0x93,0xB5}[0])  - syntax error
{0xAB,0x13,0xF9,0x93,0xB5}               - syntax error
({0xAB,0x13,0xF9,0x93,0xB5})             - see above
(char[])({0xE3,0x83,0xA2,0xA4,0xCB})     - error: cast to incomplete type 'char []' (clang)
Run Code Online (Sandbox Code Playgroud)

和一些更疯狂的组合我很惭愧写在这里......

请记住:我希望创建一个新的变量来保存阵列.

c arrays hardcoded

38
推荐指数
4
解决办法
4157
查看次数

“来自整数的指针/来自没有强制转换的指针的整数”问题

这个问题旨在成为整数和指针问题之间所有初始化/分配的常见问题解答条目。


我想编写代码,将指针设置为特定的内存地址,例如0x12345678. 但是当用 gcc 编译器编译这段代码时,我得到“初始化使指针从整数而不进行强制转换”警告/错误:

int* p = 0x12345678;
Run Code Online (Sandbox Code Playgroud)

类似地,这段代码给出了“初始化从指针生成整数而不进行强制转换”:

int* p = ...;
int i =  p;
Run Code Online (Sandbox Code Playgroud)

如果我在变量声明行之外做同样的事情,消息是一样的,但说的是“赋值”而不是“初始化”:

p = 0x12345678; // "assignment makes pointer from integer without a cast"
i = p;          // "assignment makes integer from pointer without a cast"
Run Code Online (Sandbox Code Playgroud)

使用其他流行编译器的测试也会给出错误/警告消息:

  • clang 说“不兼容的整数到指针转换”
  • icc 说“类型的值int不能用于初始化类型的实体int*
  • MSVC (cl) 说“初始化int*在间接级别上与int”不同。

问题:上面的例子是有效的 C 吗?


还有一个后续问题:

这不会给出任何警告/错误:

int* p = 0;
Run Code Online (Sandbox Code Playgroud)

为什么不?

c pointers casting initialization assignment-operator

12
推荐指数
1
解决办法
2000
查看次数

如何在C中汇总所有命令行参数?

我有一个任务.该程序将打印C中所有命令行参数的总和.我尝试编译它的代码,但在控制台中传递参数后抛出错误.下面是代码.

/* Printing sum of all command line arguments */
#include <stdio.h>

int main(int argc, char *argv[]) {
    int sum = 0, counter;

    for (counter = 1; counter <= argc; counter++) {
       sum = atoi(sum) + atoi(argv[counter]);
    }
    printf("Sum of %d command line arguments is: %d\n", argc, sum);
}
Run Code Online (Sandbox Code Playgroud)

编译后显示Segmentation fault(core dumped)错误.您的经验可以解决我的问题.

以下是我编辑的代码:

/* Printing sum of all command line arguments*/
#include <stdio.h>
#include <stdlib.h> // Added this library file

int main (int argc, char *argv[]) {
    int …
Run Code Online (Sandbox Code Playgroud)

c syntax-error atoi command-line-arguments

7
推荐指数
3
解决办法
1790
查看次数

C:两个void指针的区别是什么类型?

如果我减去两个void指针,我得到指针位置之间的相对距离(至少在我的测试系统上).我应该使用什么类型来存储结果,以便它与64位系统兼容?size_t是正确的类型还是长?

背景:我们需要检查给定的void指针是否可以安全地用作双指针.我们曾经将指针强制转换为int并检查低三位是否为零,但是我们当前的编码标准不再允许将指针转换为整数类型.我正在考虑计算void指针和NULL指针之间的差异,并检查该差异是否可以被8分割.假设NULL指针始终是8字节对齐的?

c pointers alignment void

3
推荐指数
1
解决办法
1320
查看次数

检查任何值是NULL还是空的最佳方法是什么?

我想知道检查空值的最佳(我的意思是性能和正确)是什么?

我知道这两种方式:

首先(我认为最好的):

对于任何指针检查:

if (value == NULL) ...
Run Code Online (Sandbox Code Playgroud)

对于int:

if (value == 0) ...
Run Code Online (Sandbox Code Playgroud)

第二:

if (value) ...
Run Code Online (Sandbox Code Playgroud)

c null if-statement

1
推荐指数
1
解决办法
358
查看次数

C - 为什么必须将NULL与之比较?

我很好奇为什么当我说我迭代地遍历链表时我必须做while (list != NULL)而不是while (!list).我认为NULL等于零或假.

来自评论:当我尝试一个while (!list)但从来没有前者时,我的程序似乎总是崩溃.每个节点都包含一个指向一段数据的void指针和一个指向下一个节点的指针.

c linked-list

0
推荐指数
1
解决办法
87
查看次数

C - 是否可以使用返回char*或int的函数?

是否有可能获得一个函数来返回一个int或一个char*取决于执行时发生的事情?我已经尝试了无效但在编译时我得到了很多警告

void int_char(char *str)
{
    if (I 'm matching a condition in my string)
        return (str);
    else
        return (0);
}
Run Code Online (Sandbox Code Playgroud)

我希望我足够清楚.PS:我是C编程的初学者

c

-1
推荐指数
1
解决办法
1126
查看次数