程序崩溃时使用char *

时间:2012-09-18 18:01:08

标签: c++ c string pointers

在运行以下代码时,我的程序意外崩溃!

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

int main(){

    char *str = NULL;
    strcpy(str, "swami");
    printf("%s", str);
    return 0;
}

但如果我喜欢这样:

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

int main(){

    char *str;
    strcpy(str, "swami");
    printf("%s", str);
    return 0;
}

此代码工作正常并生成正确的输出!

我正在使用gcc编译器(codeblocks IDE)。此外,这两个代码都会导致DevCpp中的程序崩溃。任何人都可以解释一下为什么会这样!?

5 个答案:

答案 0 :(得分:23)

您无法写入NULL指针。

在第二种情况下,您的指针被随机初始化为程序内存中的有效位置。这就是为什么你可以strcpy进入它。

将两个程序更改为

str = malloc(size)

calloc之前的strcpy选项。 (size是您要保留的空间大小。)

根据评论,您还可以将str的声明更改为char str[6](或更多)。

上次编辑:我将向您展示显示程序内存和指针的图片:

enter image description here

灰色区域和红色区域是禁止的(您不能写入或读取它们;顶部灰色区域用于内核内存,而其他区域是尚未回收的空间)。底部的红色区域是特殊的0页面。由于NULL0,您的str = NULL会指向此,并且您的计划将失败。

如果您没有为str分配任何内容,它将最终随机指向。它仍然可以指向红色区域或灰色区域 - &gt;你的程序将失败。它可以指向绿色或蓝色(两个色调)区域,使您的程序工作(除了它指向只读位置并且您写入它的情况)。指针的分配区域使其指向绿色区域,将其放大到顶部。

另一个选项,str[6]将堆栈区域放大到底部。所有局部变量都有空间保留到堆栈中,而分配有mallocrealloccalloc和其他朋友的所有空间都会进入堆中。

最后,请查看有关char[]char *之间差异的blog article

PS:如果你想使用GNU扩展,你可以查看asprintf函数。它会为字符串分配空间并在那里写一些内容:

asprintf(&str, "swami");

asprintf(&str, "%d + %d == %d\n", 1, 2, 3);

但是,如果你想要便携性,那就远离这个功能。

答案 1 :(得分:4)

在两个版本中都没有分配内存来复制字符串,因此两者都调用未定义的行为。第一个崩溃是因为您明确地将str初始化为NULL,因此strcpy取消引用NULL指针,该指针在大多数系统上崩溃。在第二个中,str指向任意内存,取消引用未初始化的指针可能会或可能不会崩溃。

答案 2 :(得分:2)

NULL中的#define NULL ((void *)0)<stdlib.h>。因此,您尝试写入无效的内存地址,导致程序崩溃。

答案 3 :(得分:1)

阅读此link

//destination =Pointer to the destination array where the content is to be copied.
char * strcpy ( char * destination, const char * source );

您将目标设置为NULL,因此您尝试将源复制为NULL。这就是崩溃的原因。你应该设置一些内存协助来复制字符串。

int main(){
      char *str=malloc(6);  //enough for "swami"+'\0'
      strcpy(str, "swami");
      printf("%s", str);
      return 0;

}

答案 4 :(得分:1)

strcpy只是复制,而不是为它创造空间。

在第一种情况下,您尝试将字符串写入代码段的开头:不是一个好主意。

在第二种情况下,你开始将字符串写入某个地方,并且在你的情况下没有崩溃做运气和编译器帮助。

您应该执行以下操作之一:

一个。分配记忆:str = new char[10]
湾使用strdup将字符串复制到一个新位置。