Сессия сегментации Sprintf

numCheck - номер между 1-1000. Этот код дает мне segfault только тогда, когда я собираю результаты sprintf в charcheck. Если я просто использую sprintf без использования результатов, я не получаю seg-ошибку. Что здесь происходит?

char * numString;
int charcheck = sprintf(numString, "%d", numCheck);

Ответ 1

Вам нужно предоставить свою собственную память для sprintf. Кроме того, не используйте sprintf, а скорее snprintf:

char buf[1000] = {0};

snprintf(buf, 999, ....);

В качестве альтернативы вы можете динамически распределять память:

char * buf = new char[BUFSIZE];
snprintf(buf, BUFSIZE-1, ...);
/* ... */
delete[] buf;

Ответ 2

Первый аргумент sprintf должен указывать на допустимый буфер. У вас есть char*, но он указывает на мусор.

Измените свой код на:

char numString[80] = { };
int charcheck = sprintf(numString, "%d", numCheck);

Итак, numString фактически указывает на допустимый буфер (из 80 символов в этом примере, все элементы которого инициализируются 0).

Было бы также полезно использовать snprintf, чтобы вы могли передать ему размер своего буфера, что поможет предотвратить переполнение буфера:

const int bufsize = 80;
char numString[bufsize] = { };
int charcheck = snprintf(numString, bufsize - 1, "%d", numCheck);

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

Ответ 3

Указатель, указанный как первый параметр sprintf, должен указывать на ячейку памяти, где sprintf должен писать форматированную строку.

В этом случае вы не инициализировали numString, чтобы указать на некоторую память, выделенную для форматированной строки. Поскольку numString не инициализируется, он может указывать в любом месте, и в вашем случае попытка записать отформатированный вывод в это место приводит к ошибке сегментации.

Ответ 4

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

char numString[50];
int charcheck = sprintf(numString, "%d", numCheck);

В вашем случае межсетевые операции sprintf пытаются ссылаться на значение NULL, которое является значением по умолчанию для указателя в вашем случае.

Ответ 5

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

char numString[80] = { };

предложенный Ситом, Иисусом и Керреком.

Я думаю, что последний ответ из sth - хорошее объяснение: "первый параметр sprintf должен указывать на ячейку памяти, где sprintf должен писать форматированную строку". Поэтому, помимо использования массива символов, который будет принудительно распределять память для строки, вы также можете использовать это:

char *numstring = (char*) malloc(80);

Это должно позволить вам явно освободить выделенную память, когда она больше не нужна.