分段写入字符串时出错

时间:2013-08-28 04:01:39

标签: c pointers memory reverse

我正在尝试编写就地反向函数并且几乎完全遵循在线代码,但运行以下程序会引发总线错误。我是否将错误的参数传递给reverse()?

void reverse(char *str) {
    char * end = str;
    char tmp;
    if (str) {
        while (*end) {
            ++end;
        }
        --end;
        while (str < end) {
            tmp = *str;
            *str++ = *end;
            *end-- = tmp;
        }
    }
}

int main() {
    char *s = "sample";
    reverse(s);
    printf("%s\n");
    return 1;
}

4 个答案:

答案 0 :(得分:16)

要知道发生了什么,你必须要了解C程序的内存布局。

char *s = "sample";    // Here the "sample" string is placed in 
                        // the read only memory of the Initialized Data segment. 

在这里,您无法修改数据。 “s”是指向char const(“示例”)的指针,您正在尝试修改char const。这就是您收到bus error错误的原因。

                        |Stack frame of main()          |
                        |char *s                        |
                        |-------------------------------|
                        |Stack frame of reverse()       |
                        |char *end                      |
                        |char tmp                       |
                        |                               |
                        |-------------------------------|
                        |                               |
                        |                               |
                        |                               |
                        |                               |
                        |                               |
                        |-------------------------------|
                        |                               |
                        |           HEAP                |
                        |                               |
                        |-------------------------------|
                        |                               |
                        |   UNINITIALIZED DATA (BSS)    |
                        |                               |
                        |-------------------------------|
                        |                               |
                        |      INITIALIZED DATA         |
                        |                               |
                        |"sample"   |                   |
                        |           |                   |
                        |(Read Only)| (Read/Write)      |
                        |-------------------------------|
                        |   Text or Code Segment        |
                        |                               |
                        |-------------------------------|

更新 的 帖子下方与您的问题无关。但是如果你知道在C中为所有变量分配的内存在哪里,那么你可以更好地编码。 以下程序可以更好地理解C程序的内存布局。 我没有在图中包含命令行参数,函数参数和函数的返回值。 想要更新这篇文章的人可以在图中添加命令行参数,函数参数和函数返回值。

|Stack frame of main()              |               
|local_To_Main                      |
|                                   |   #include <stdio.h>
|-----------------------------------|   #include <stdlib.h>
|Stack frame of function1()         |   int gVariable1 = 100;
|local_To_Function1                 |   int gVariable2;
|iptr                               |   char cstring[10] = "Hello";
|     \               STACK         |   char* cptr = "Hello World";
|------\---------------|------------|   void function1(void)
|       \             \|/           |   {
|        \                          |       static int j = 5;
|         \                         |       int local_To_Function1;
|          \                 ^      |       int *iptr;
|           \                |      |       iptr = (int *) malloc(sizeof(int));
|------------\---------------|------|       free(iptr);
|   HEAP      \       ---           |   }
|              \---> |int|          |   
|                     ---           |   int main(void)
|-----------------------------------|   {
|                                   |       static int i;
|   UNINITIALIZED DATA (BSS)        |       int local_To_Main;
|gVariable2(initialized to 0)       |   
|i (initialized to 0)               |
|-----------------------------------|       function1();
|                                   |       return 0;
|      INITIALIZED DATA             |   }
|                                   |
|"Hello World"  |gVariable1 =100    |
|       ^       |cstring="Hello"    |
|       |       |j=5                |
|       |---<---<---- cptr          |
|(Read Only)    | (Read/Write)      |
|-----------------------------------|
|   Text or Code Segment            |
|                                   |
|-----------------------------------|

答案 1 :(得分:4)

您可能想要更改

char *s = "sample";  //Pointer to string literal

char s[] = "sample";  // mutable copy of string literal

尝试修改字符串文字是未定义的行为,它们应该用作const char *


可能不相关,但有建议,

当您执行*end--之类的操作时,您可能需要放置paranthesis,以便它能够执行您认为的操作。

以上可以

(*end)--

 *(end--)

你需要很好地掌握优先规则,以确定你想要的是正在发生的事情。

答案 2 :(得分:3)

您的反向功能完全正确。主要功能部分只是一些事情:

  • 正如KarthikT所说,s应该是char[]而不是char*,因为更改字面值是未定义的。

  • 你的printf函数中的
  • ,你忘了把s作为参数。

  • return 0成功。 return 1是错误的。

所以新的主要应该是:

int main() {
    char s[] = "sample";
    reverse(s);
    printf("%s\n", s);
    return 0;
}

输出:

elpmas

答案 3 :(得分:1)

char *str="sample";

此处示例存储在只读存储器中,因此您永远不能对此类文字进行修改。

为了进行操作,您必须将文字存储在读写内存中。 以下代码可以解决您的问题。

#include<stdio.h>
void reverse(char *str) 
{
    char temp,*end;
    for(end=str;*end;end++);
    end--; 
    for(;str<end;temp=*str,*(str++)=*end,*(end--)=temp);
}

int main() 
{
    char str[]="sample"; //stored in read-write memory
    reverse(str);
    printf("%s\n",str);
return 0;
}

输出:

elpmas