Ошибка сегментации с использованием strcat - PullRequest
1 голос
/ 25 ноября 2011

Вот мой код:

char *name, name_log="log-";

------ получение имени от пользователя -----

strcat(name_log, name);
char ext[] = ".log";
strcat(name_log, ext);

Что мне нужно в конечном итоге, это name_log = "log-'name'.log", но я получаю ошибку ошибки сегментации: ((. Что я делаю не так и как я могу это исправить? Thx

Ответы [ 5 ]

3 голосов
/ 25 ноября 2011

строковым литералам выделяется фиксированный объем памяти, как правило, в разделе «только для чтения», вместо этого вам необходимо использовать буфер.нужно использовать что-то, что проверяет размер буфера, который он использует, или с ограничениями на то, что он может объединять, например strncat.

2 голосов
/ 25 ноября 2011

Совершенно другое решение будет следующим:

const char *prefix = "log-";
const char *suffix = ".log";
// There's a "char *name" somewhere
int size_needed;
char *result;

size_needed = snprintf(NULL, 0, "%s%s%s", prefix, name, suffix);
result = malloc(size_needed + 1);
snprintf(result, size_needed + 1, "%s%s%s", prefix, name, suffix);

// "result" now contains the desired string.

Приятная вещь в snprintf состоит в том, что он возвращает количество символов, которые он напишет, если будет достаточно места.Это можно использовать, предварительно измеряя объем выделяемой памяти, что делает ненужными сложные и подверженные ошибкам вычисления.

Если вы оказались в системе с asprintf, это еще проще:

char *result = NULL /* in case asprintf fails */;
asprintf(&result, "log-%s.log", name);
// "result" must be released with "free"
2 голосов
/ 25 ноября 2011

Для начала, если , то это ваш код:

char *name, name_log="log-";

затем name_log - это символ, не указатель на символ.

Предполагая, что это опечатка, вы не можете добавлять строковые литералы подобным образом. Модификации строковых литералов - неопределенное поведение.

Для строки переменного размера, как, по-видимому, user, возможно, самый безопасный вариант - выделить еще одну строку, достаточно большую для хранения результата, что-то вроде:

char *name, *name_log = "log-", *ext = ".log";
// Do something to allocate and populate name
char *buffer = malloc (strlen (name_log) + strlen (name) + strlen (ext) + 1);
if (buffer == NULL) {
    // Out of memory.
} else {
    strcpy (buffer, name_log);
    strcat (buffer, name);
    strcat (buffer, ext);
    // Do something with buffer.
    free (buffer);
}

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

0 голосов
/ 25 ноября 2011

name_log указывает на статическое место: "log-", что означает, что не может быть изменено, в то время как в качестве первого параметра в strcat() он должен быть изменяемым.

попробуйте изменить тип name_log char* на char[], например,

char[20] name_log = "log-";
0 голосов
/ 25 ноября 2011

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

вы можете сделать

char[20] strarray;

strcat(strarray, "log-");
strcat(strarray, "abcd");
...