为什么此C程序在运行时引发分段错误? [英] Why this C program throws segmentation fault at runtime?

查看:48
本文介绍了为什么此C程序在运行时引发分段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将字符数组声明为char *字符串.然后我声明另一个指针,该指针再次引用原始字符串,然后当我要更改该字符串上的任何内容时,在运行时程序会抛出分段错误.

I'm declaring character array as char* string. And then I declare other pointer which again refer to original string, then when I'm going to change any thing on that string, at runtime program throws segmentation fault.


#include <string.h>

#include <ctype.h>

int main(void)

{

char* s = "random";

char* t = s;

 *t = 'R'; // ----> Segmentation fault

 t[0] = toupper(t[0]); // ----> Segmentation fault

 *s = 'R'; // ----> Segmentation fault

 s[0] = 'R'; // ----> Segmentation fault

printf("s is : %s , address : %p \n", s,s);

printf("t is : %s , address : %p \n", t,t);

return 0;

}

即使这是无效:

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

int main(void)
{
char *p = "random";
*p = 'N'; // ----> Segmentation fault

return 0;
}

推荐答案

我将字符数组声明为char *字符串.

I'm declaring character array as char* string.

这是您的问题开始的地方!尽管指针和数组在语法上有一些共同点,但它们 不相同 .在下面复制的行中,您正在做的是将 s 声明为指向 char 指针,并使用字符串文字的地址初始化该指针您提供.

This is where your problems begin! Although pointers and arrays have some things in common, syntactically, they are not the same. What you are doing in the line copied below is declaring s as a pointer to a char and initializing that pointer with the address of the string literal you provide.

char* s = "random";

作为字符串文字,编译器可以(尽管不是必须执行)为只读存储器中的数据分配存储器;因此,当您尝试(稍后)修改由 s 变量(或其中的地址)指向的字符(或其他任何指针,例如您的 t 时,相同的地址),您将遇到不确定的行为.某些系统会导致您的程序崩溃(分段错误"),其他系统可能会无声地让您逃脱".确实,您甚至可能在不同的时间使用相同的代码获得不同的结果.

As a string literal, the compiler is allowed to (though not obliged to) allocate memory for that data in read-only memory; thus, when you attempt (later) to modify the character pointed to by (the address in) the s variable (or any other pointer, such as your t, which contains the same address), you will experience undefined behaviour. Some systems will cause your program to crash ("Segmentation fault"), others may silently allow you to 'get away' with it. Indeed, you may even get different result with the same code at different times.

要解决此问题,并正确声明一个字符数组,请使用 [] 表示法:

To fix this, and to properly declare a character array, use the [] notation:

char a[] = "random";

这会将 a 声明为(可修改的)字符数组(在这种情况下,其大小由您赋予它的初始值- 7 确定),其中包含终止的 nul 字符);然后,编译器将使用字符串文字数据的副本来初始化该数组.然后,您可以随意使用 * a 之类的表达式来引用该数组的第一个元素.

This will declare a as a (modifiable) array of characters (whose size is determined, in this case, by the initial value you give it - 7, here, with the terminating nul character included); then, the compiler will initialize that array with a copy of the string literal's data. You are then free to use an expression like *a to refer to the first element of that array.

以下简短程序可能会有所帮助:

The following short program may be helpful:

#include <stdio.h>
int main()
{
    char* s = "random";
    *s = 'R'; // Undefined behaviour: could be ignored, could crash, could work!
    printf("%s\n", s);
    char a[] = "random";
    *a = 'R'; // Well-defined behaviour - this will change the first letter of the string.
    printf("%s\n", a);
    return 0;
}

(您可能需要注释掉使用 s 的行,以使代码运行到其他行!)

(You may need to comment-out the lines that use s to get the code to run to the other lines!)

这篇关于为什么此C程序在运行时引发分段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆