指针初始化怀疑

时间:2011-01-06 04:29:47

标签: 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)。

请告诉我们发生了什么

1 个答案:

答案 0 :(得分:5)

你的第一个例子是seg faulting,因为你试图取消引用你用该行创建的空指针:

int *i=0;

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

第二个代码段有效,因为您实际上已经使用malloc为您的指针分配了内存,您可以取消引用它。我认为你可以获得非零值,具体取决于你用malloc分配的地址旁边的内存。我这样说是因为通常一个int是4个字节而你只分配了2.当取消引用int指针时,它应该根据指向的4个字节将值作为int返回。在你的情况下,前两个字节是你从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”,你的程序很可能是seg-fault。你需要了解的关于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;
}