Coredump при работе над функцией, которая переворачивает строку - PullRequest
1 голос
/ 20 апреля 2011
#include  <stdio.h>
#include  <string.h>

main()
{
    char tmpChar;
    char *str_1 = "Hello";

    int index;
    int len = strlen(str_1);
    for (int i = 0; i < len/2; i++)
    {
        index = len - 1- i;
        tmpChar = str_1[len - i -1];
        str_1[index] = str_1[i]; <<<<<--------------- core dumps at this point. Not sure why
        str_1[i] = tmpChar;
        printf("str_1[%d] = %c\n", i, str_1[i]);
    }
    str_1[len] = '\0';
    printf("str_1 = %s\n", str_1);
}

Ответы [ 3 ]

5 голосов
/ 20 апреля 2011

Вы пытаетесь изменить содержимое строкового литерала, который вызывает неопределенное поведение.Строковые литералы обычно хранятся в разделе памяти, доступном только для чтения, и имеют статическую продолжительность хранения.

char *str_1 = "Hello";.В этом случае "Hello" является строковым литералом (хранится в разделе только для чтения), и вы пытаетесь изменить содержимое, выполнив это

str_1[index] = str_1[i];

Вместо того, чтобы str_1 указывать на литерал [т.е.char *str_1 = "Hello"] сделать его массивом символов, т.е. char str_1[] = "Hello".Содержимое литерала будет скопировано в стек, и вы не получите никакого segfault, если попытаетесь изменить содержимое.

3 голосов
/ 20 апреля 2011

Изменение

char *str_1 = "Hello"; //read only

в

char str_1[] = "Hello";
1 голос
/ 20 апреля 2011

В стандарте ISO C99 говорится о строковых литералах (раздел 6.4.5 / 6):

Не определено, различаются ли эти массивы при условии, что их элементы имеют соответствующие значения. Если программа пытается изменить такой массив, поведение не определено.

Это потому, что, как правило, все строковые литералы объединены в одну область, которая может быть помечена только для чтения, и иногда они объединяются для экономии места. Другими словами, два строковых литерала:

char *p1 = "Googolplex";
char *p2 = "plex";

может храниться таким образом:

  +--- p1           p2 ---+
  |                       |
  V                       V
+---+---+---+---+---+---+---+---+---+---+----+
| G | o | o | g | o | l | p | l | e | x | \0 |
+---+---+---+---+---+---+---+---+---+---+----+

Это значит: не пытайтесь их модифицировать. Он может работать в определенных ситуациях, но на это не стоит полагаться, если вы хоть немного цените переносимость.

Изменение:

char *str_1 = "Hello";

до:

char str_1[] = "Hello";

, так как это фактически совпадает с:

char str_1[6];
strcpy (str_1, "Hello");
...