2013-05-13 7 views
2

Я пишу консольное приложение Win32 в Visual Studio 2010.Характер повторного использования массива

Рассмотрим одну функцию, взять два char* в качестве параметров.

Ниже прототип функции:

void WriteApplicationFile(char *mappname,char* MessageString) 
{ 
    //Do some File related stuffs. 
} 

Теперь следующие вызовы работают отлично:

WriteApplicationFile("FirstOne", "Append Me"); 
WriteApplicationFile("FirstOne", "Append Another"); 

Но если я попробовать то же самое с некоторыми символьный массив вещь это даст мне утверждение, и бросить меня на сборку.

Следующий код не работает:

char * LocalBuffer = new char[100]; 
sprintf(LocalBuffer,"Number of jobs in Queue %d",JobsCount); 
WriteApplicationFile("SAAZshadowProtect",LocalBuffer); 
free(LocalBuffer); 
LocalBuffer = NULL; 
//Work fine. 
//... 
LocalBuffer = new char[100]; 
sprintf(LocalBuffer,"Log file name %s",LogFileCharName); 
WriteApplicationFile("SAAZshadowProtect",LocalBuffer); 
free(LocalBuffer); // I got assertion here.. 
LocalBuffer = NULL; 

Где я буду неправильно?

Еще одна вещь в том, что я хочу обрабатывать все утверждения и ошибки с помощью блока try-catch. Как мне это сделать?

+0

использовать простой старый malloc, если вы на C. и освобождаетесь, чтобы перераспределить одинаковый размер? только это дает мне озноб ... memset существует не просто так. – BigMike

+0

Кажется, что переполнение буфера произошло до Localbuffer. – doptimusprime

+0

Проверьте, не произошла ли перезапись памяти. – doptimusprime

ответ

13

При использовании new[] вы должны использовать delete[], а не free() или delete. Заменить:

free(LocalBuffer); 

с:

delete[] LocalBuffer; 

Там, кажется, нет никаких причин, чтобы динамически выделять память. Размер буфера - это постоянная времени компиляции, невелика (без переполнения стека), и, как представляется, буфер не должен выходить за пределы области, в которой он был выделен.

Как это C++ настоятельно рекомендуется использовать std::string, который будет обрабатывать динамическое управление памятью для вас и std::ostringstream, который типизированного и избегает спецификации фиксированного размера буфера вместо sprintf():

#include <sstream> 
#include <string> 

std::ostringstream out; 
out << "Number of jobs in Queue " << JobsCount; 
const std::string s(out.str()); 

Если доступ к C-стиля строка обязательна использовать std::string::c_str().

Кроме того, типы аргументов WriteApplicationFile() являются char*, не const char*, поэтому прохождения строковой функции будет вызывать неопределенное поведение если функция изменяет аргументы.

+0

Нет, это снова дайте мне утверждение на строку кода delete [] LocalBuffer; –

+0

И я не могу использовать std :: как предложил один мой старший человек. –

+3

@SantoshDhanawade, 1) выяснить, почему 'std ::' запрещено и почему ваша жизнь становится сложнее. 2) 'new char []', за которым следует 'delete []', не будет причиной утверждения. Удалите части кода до тех пор, пока ошибка не исчезнет, ​​а затем повторно введите код, чтобы найти источник ошибки или опубликовать больше кода, чтобы люди могли комментировать. – hmjd

2

Во-первых, вы программируете на C или на C++. Код, который вы представляете , выглядит как C, но вы говорите о блоке try/catch, который может только быть C++.

В C++ используйте std::ostringstream и std::string. Любое другое решение для просто неверно.

В C вы должны использовать snprintf, а не sprintf. Это практически невозможно использовать sprintf безопасно. (Например, сколько символов находятся в LogFileCharName.) И не используйте динамическое распределение , когда вам это не нужно.(Это справедливо и для C++, как скважины;. Не должно быть никаких new или delete (ни malloc, ни free) в коде вы показываете

Как что происходит не так, есть по крайней мере два возможных проблем в код показать: вы выделение памяти с new[], но освобождая его free (неопределенного поведение), и вы не проверяете длину LogFileCharName перед тем вызывающему sprintf, чтобы вы могли быть перезапись конца буфера .

Смежные вопросы