проблема strcat с char * a [10] - PullRequest
1 голос
/ 17 июля 2010

включает

#include <string.h>

int main()
{
        char *array[10]={};
        char* token;
        token = "testing";
        array[0] = "again";
        strcat(array[0], token);
}

почему возвращается ошибка сегментации?

Я немного растерялся.

Ответы [ 5 ]

6 голосов
/ 17 июля 2010

Технически, это недопустимый C. (Это действительно C ++.)

char *array[10]={};

Вы должны использовать

char *array[10] = {0};

Это объявляет массив из 10 указателей наchar и инициализирует их все нулевыми указателями.

char* token;
token = "testing";

Это объявляет токен как указатель на char и указывает его на строковый литерал, который не модифицируется.

array[0] = "again";

Это указываетпервый char указатель array на строковый литерал, который (опять же) является неизменяемой последовательностью char.

strcat(array[0], token);

strcat объединяет одну строку в конец другой строки.Чтобы это работало, первая строка должна содержаться в доступном для записи хранилище и иметь достаточно избыточного хранилища, чтобы содержать вторую строку после первого завершающего нулевого символа ('\ 0') и после него в первой строке.Ни один из них не относится к array[0], который указывает непосредственно на строковый литерал.

Что вам нужно сделать, это что-то вроде этого.(Вам нужно #include <string.h> и <stdlib.h>.)

Я пошел для расчета размеров во время выполнения и динамического распределения памяти, так как я предполагаю, что вы делаете тест для того, гдестроки могут не иметь известного размера в будущем.Со строками, известными во время компиляции, вы можете избежать некоторой (или большей части) работы во время компиляции;но тогда вы можете сделать "againtesting" как однострочный литерал.

char* token = "testing";
char* other_token = "again";

/* Include extra space for string terminator */
size_t required_length = strlen(token) + strlen(other_token) + 1;

/* Dynamically allocated a big enough buffer */
array[0] = malloc( required_length );
strcpy( array[0], other_token );
strcat( array[0], token );

/* More code... */

/* Free allocated buffer */
free( array[0] );
2 голосов
/ 17 июля 2010

Как это работает: char *array[10] - это массив из 10 char * указателей (в основном 10 таких же вещей, как token).

token = "testing" создает статическое пространство где-то в памяти вашей программы во время сборки и помещает туда «тестирование». Затем во время выполнения устанавливает адрес для этого статического "тестирования" в token.

array[0] = "again" делает в основном то же самое.

Затем strcat(array[0], token) берет адрес в array[0] и пытается добавить содержимое token в строку по этому адресу. Что дает вам segfault, поскольку array[0] указывает на сегмент данных только для чтения в вашей памяти.

Как это сделать правильно:

char * initial = "first"; // pointer to static "first" string
char * second = "another"; // another one
char string[20]; // local array of 20 bytes

strcpy(string, initial); // copies first string into your read-write memory
strcat(string, second); // adds the second string there

На самом деле, если вы не хотите стрелять себе в ногу, лучший способ сделать что-то вроде последних двух строк:

snprintf(string, sizeof(string), "%s%s", initial, second);

snprintf затем гарантирует, что вы не используете более 20 байтов string. strcat и strcpy с радостью перейдут через ограничение в недопустимую память и вызовут еще один segfault во время выполнения или что-то еще хуже (например, эксплойты безопасности), если скопированная строка будет длиннее, чем пространство назначения.

0 голосов
/ 17 июля 2010

Вы помещаете строку в array[0], которая является только одним символом.Используйте array[0]='a' вот так.

0 голосов
/ 17 июля 2010

Если вы планируете изменить соответствующие строки, вам действительно следует выделить достаточно памяти для того, что вам нужно.Например, вместо char *token; token = "testing"; вы можете использовать, скажем, char token[20] = "testing";, что дает достаточно места для строки из 19 символов (плюс нулевой байт в конце).

Аналогично, вы можете использовать char array[10][20] = {"testing"};создайте массив из 10 строк и установите первую для тестирования.

0 голосов
/ 17 июля 2010

Чтобы создать массив символов, char *array[10]={}; должно быть char array[10]={};

ошибка сегментации возникает из-за того, что массив [0] указывает на «снова», строковый литерал, а модификация строковых литералов - нет-нет (неопределенное поведение)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...