Программа 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;
}