Программа strcat в c не работает

#include<string.h>
#include<stdio.h>
void main()
{
    char *str1="hello";
    char *str2="world";
    strcat(str2,str1);
    printf("%s",str2);
}

Если я запускаю эту программу, я получаю завершение программы во время выполнения.

Пожалуйста, помогите мне.

Если я использую это:

char str1[]="hello";
char str2[]="world";

тогда это работает!

Но почему

char *str1="hello";
char *str2="world";

этот код не работает????

6 ответов

Решение

Вы учитесь на плохой книге. Основная функция должна быть объявлена ​​как

int main (void);

Объявление его как void вызывает неопределенное поведение при завершении приложения. Ну, это еще не закончено, но в конце концов это будет.

Получить книгу о языке Си. Вы найдете это

char *srt1="hello";

составляется так, как будто вы написали

static const char secret_array [6] = { 'h', 'e', 'l', 'l', 'o', 0 };
char* srt1 = (char*) &secret_array [0];

в то время как

char srt1[]="hello";

составляется так, как будто вы написали

char srt1 [6] = { 'h', 'e', 'l', 'l', 'o', 0 };

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

В вашем коде.

char *srt1="hello";

Вы создали указатель и указали на постоянную строку. Компилятор помещает это в часть памяти, которая помечена как доступная только для чтения.

Так strcat постараюсь изменить то, что вызывает неопределенное поведение.

он не имеет имени и имеет статическую длительность хранения (это означает, что он живет в течение всей жизни программы); и переменная типа pointer-to-char, называемая p, которая инициализируется расположением первого символа в этом безымянном массиве только для чтения.

см. мой ответ для правильного понимания, почему это работает для первого, а не для второго случая.

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

Это:

char *srt2="world";

средства srt2 (плохое имя, кстати) - переменная-указатель, указывающая на память, содержащую постоянные данные "world" (и заканчивая '\0' персонаж). Там нет дополнительного места после шести символов, и вы даже не можете изменить буквы.

Тебе нужно:

char str2[32] = "world";

Это, с другой стороны, делает str2 быть массивом из 32 символов, где первые 6 символов инициализируются в "world" и завершающий '\0', К этому можно добавить, поскольку новые символы могут вписываться в существующий массив, если вы не переступаете и пытаетесь сохранить более 32 символов (включая терминатор).

char *srt1="hello";
char *srt2="world";

когда вы объявляете строку таким образом, она сохраняется в постоянной памяти!

Вы не можете изменять переменные, хранящиеся в постоянной памяти!

Когда вы делаете strcat он пытается изменить строку, которая присутствует в постоянной памяти. Так что здесь это запрещено! Это "неопределенный".

В вашей программе str1 и str2 не должны записываться, потому что они объявлены как указатель на постоянную память. Чтобы увидеть это, выполните 'objdump -s a.out', и вы увидите следующее:

Contents of section .rodata:
400640 01000200 68656c6c 6f00776f 726c6400  ....hello.world.
400650 257300                               %s.    

strcat пытается выполнить запись в эту часть памяти, что вызывает ошибку сегментации.

Вы также можете использовать массив. Вот моя простая программа, где я столкнулся с такой проблемой, но в этой задаче вы должны объявить размер массива. Подобно, mahe = [10],

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char cname[10] = "mahe";
    strcat(cname, "Karim");
    printf("%s\n", cname);
    return 0;
}
Другие вопросы по тегам