【问题标题】:program crash while using char*使用 char* 时程序崩溃
【发布时间】:2012-09-23 04:08:11
【问题描述】:

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

#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 编译器(代码块 IDE)。此外,这两个代码都会导致 DevCpp 中的程序崩溃。谁能解释一下为什么会这样!?

【问题讨论】:

  • 在使用 strcpy 之前,需要为此分配必要的内存。您想要CC++ 解决方案吗?第二个不能正常工作,它是未定义的行为,你很幸运它可以工作。

标签: c++ c string pointers


【解决方案1】:

您不能写入NULL 指针。

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

将两个程序更改为具有

str = malloc(size)

callocstrcpy 之前的选项。 (size 是您要预留的空间大小。)

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

最后编辑:我将向您展示这张显示程序内存和指针的图片:

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

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

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

最后,看看blog article 了解char[]char * 之间的区别。

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

asprintf(&str, "swami");

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

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

【讨论】:

  • 您也可以使用char str[6],以后不必释放内存。
  • 是的,但这与使用标题中的char * 不同。我也会添加这个选项。
  • 好的,然后使用char buffer[6]; char *str = buffer;
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      阅读此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;
      

      }

      【讨论】:

      • 匿名否决票是怎么回事?如果答案没有用,请发表评论,以便改进。
      【解决方案5】:

      strcpy 只是复制,不为其生成空间。

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

      在第二种情况下,您开始将字符串写入某个地方,并且在您的情况下没有崩溃,可能是因为运气好,也许编译器有帮助。

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

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

      【讨论】:

        猜你喜欢
        • 2018-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-29
        相关资源
        最近更新 更多