linux - 指针初始化疑惑

标签 linux pointers gcc malloc

我们可以在 C 中像这样初始化一个字符指针。

char *c="test";

其中c指向第一个字符(t)。

但是当我给出如下代码时。它给出了段错误。

#include<stdio.h>
#include<stdlib.h>
main()
{

    int *i=0;
    printf("%d",*i);
}

还有当我给

#include<stdio.h>
#include<stdlib.h>
main()
{
    int *i;
    i=(int *)malloc(2);
    *i=0;
    printf("%d",*i);
}

有效(输出 0)。

当我给出 malloc(0) 时,它起作用了(给出输出 0)。

请告诉我发生了什么

最佳答案

您的第一个示例是段错误,因为您正试图取消引用您使用以下行创建的空指针:

int *i=0;

你不能取消引用一个不指向任何东西的指针并期待好事发生。 =)

第二个代码段有效,因为您实际上已经使用 malloc 将内存分配给您的指针,您可以取消引用。我认为您有可能获得零以外的值,具体取决于与您使用 malloc 分配的地址相邻的内存。我这样说是因为通常一个 int 是 4 个字节,而您只分配了 2 个字节。当取消引用 int 指针时,它应该根据指向的 4 个字节将值作为 int 返回。在您的情况下,前 2 个字节是您从 malloc 收到的内容,相邻的 2 个字节是可能是任何内容的任何内容,无论它是什么,都将被视为 int。你可能会遇到这样的奇怪行为,你应该分配你尝试使用/指向的类型所需的内存大小。
(即 int *i = (int *) malloc(sizeof(int)); )

一旦指针指向大小正确的内存,您就可以这样设置值:

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

int main (int argc, char *argv[])
{
    int *i = (int *)malloc(sizeof(int));
    *i = 25;
    printf("i = %d\n",*i);

    *i = 12;
    printf("i = %d\n",*i);
    return 0;
}

根据评论编辑:

指针指向内存,而不是值。初始化 char *ptr="test"; 时,您不是在分配“test”的值,而是在分配编译器放置“test”的内存地址,该地址位于您的处理数据段并且是只读的。如果您尝试修改字符串“test”,您的程序可能会出现段错误。关于 char *,您需要了解的是它指向字符串中的单个(即第一个)字符。当您取消引用 char * 时,您将看到 1 个字符和一个字符。 C 使用以空字符结尾的字符串,并注意您在调用 printf 时没有取消引用 ptr,您将指针本身传递给它并且指向第一个字符。如何显示取决于传递给 printf 的格式。当 printf 传递 '%c' 格式时,它将打印 ptr 指向的单个字符,如果传递 '%p' 格式,它将打印 ptr 指向的地址。要获取整个字符串,请将“%s”作为格式传递。这使得 printf 所做的是从您传入的指针开始并读取每个连续的字节,直到达到 null。下面是一些演示这些的代码。

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

int main (int argc, char *argv[])
{
    // Initialize to data segement/read only string
    char *ptr = "test";
    printf("ptr points at     = %p\n", ptr);   // Prints the address ptr points to
    printf("ptr dereferenced  = %c\n", *ptr);  // Prints the value at address ptr
    printf("ptr value         = %s\n", ptr);   // Prints the string of chars pointed to by ptr

    // Uncomment this to see bad behavior!
    // ptr[1] = 'E'; // SEG FAULT -> Attempting to modify read-only memory

    printf("--------------------\n");

    // Use memory you have allocated explicitly and can modify
    ptr = malloc(10);
    strncpy(ptr, "foo", 10);
    printf("ptr now points at = %p\n", ptr);   // Prints the address ptr points to
    printf("ptr dereferenced  = %c\n", *ptr);  // Prints the value at address ptr
    printf("ptr value         = %s\n", ptr);   // Prints the string of chars pointed to by ptr

    ptr[1] = 'F';  // Change the second char in string to F
    printf("ptr value (mod)   = %s\n", ptr);
    return 0;
}

关于linux - 指针初始化疑惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4611751/

相关文章:

mysql - 在数据库中保存后缀电子邮件副本

linux - BASH - while 循环不重新检查文件

c++ - 打开文件流时在 unix 终端中生成编译器错误,但在 visual studio 2013 中不生成

linux - 安装 OpenCV 时出错

c - 是否不允许对操作的左值进行类型转换?

c - C 中的指针和数组 - 极其困惑

c++ - 如何使用单个字符指针将 float 转换为字符串?

c++ - gcc 4.9.2编译错误: AssetLinkData

c++ - 如何使用 android-ndk 优化 native 代码(速度优化)

c - 如何使用 gcov 对动态库进行单元测试?