2013-02-17 5 views
-2

Как освободить память что-то вроде этого (Visual Studio 2008 - Win32/консоли):C++ как освободить память * char?

я могу включать в себя только: iostream

#include <iostream> 

void data_t(char *test[]) 
{ 
    test[0] = new char[]; 
    test[1] = new char[]; 
    test[0] = "Test1"; 
    test[1] = "Test2"; 
} 

int main() 
{ 
    char *test[2]; 
    data_t(test); 
    cout<<test[0]<<"\n"; 
    cout<<test[1]<<"\n"; 
    delete[] test[0];//Debug assertion failed! - The program '[7884] Zadanie_4_sortowanie.exe: Native' has exited with code 3 (0x3). 
    delete[] test[1]; 
} 

Что я сделал не так?

+4

Что означает 'новый символ []', предназначенный для обозначения? Это не законный C++. – jalf

+0

Печально, что MSVS принимает такие вещи. Интересно, что он с этим делает? –

+1

Оператор-ассистент на указателях символов не копирует данные, он просто меняет его, просто назначает указатель. Итак, предположим, что вы исправили 'new []' s, чтобы быть, скажем, 'new [6]', чтобы эти две строки работали, вы сразу же просачиваете эту память, перенаправляя оба указателя, чтобы указать на строковые литералы. Ошибка возникает, потому что вы можете только «удалить []» то, что вы выделили с помощью «new []», и эти указатели в настоящее время указывают на литералы. Короткая версия, используйте 'std: string', если вы можете и понимаете c-манипуляцию строки, если вы должны использовать буферы символов с нулевым завершением. – dmckee

ответ

1

Поскольку «Test1» и «Test2» используются вашей программой во время выполнения (они печатаются cout), компилятор должен их где-то сохранять. Он делает это, помещая их в свой исполняемый файл.

Поскольку они уже находятся в вашем исполняемом файле, нет никаких причин для выделения новой памяти. Итак, вы можете удалить первые две строки в data_t.

Если вы сделаете это, вы получите ошибку компилятора, хотя эта ошибка должна быть уже там, что будет жаловаться на то, что вы пытаетесь назначить строковый литерал («Test1», «Test2») в не const-массив ,

Проблема заключается в том, что строки, сохраненные компилятором в исполняемый файл, НЕ должны быть изменены. Вы только печатаете их, но data_t этого не знает. Чтобы исправить эту проблему, вы должны использовать const char * вместо char *

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

5

char[] является неполным типом и не может использоваться в выражении new. Вы должны фактически принять решение о размере массива, например:

char * p = new char[200]; 

Тогда вы можете сказать delete[] p;, когда вы закончите.

Вам необходимо что-то вроде strcpy для копирования данных вchar. Присвоение, которое вы написали, только перезаписывает указатель, теряя при этом динамическое распределение (то есть утечку). (На самом деле, вы, возможно, не потребуется динамическое выделение на всех, если вы просто хотите, фиксированные строки, поэтому просто удалите строки с new и delete в них.)


То, что вы действительно хотите, однако, является std::array<std::string, 2>, хотя:

#include <array> 
#include <string> 
#include <iostream> 

std::array<std::string, 2> test = { "Test1", "Test2" }; 
std::cout << test[0] << "\n" << test[1] << "\n"; 

Или передать его по ссылке:

void populate(std::array<std::string, 2> & a) 
{ 
    a[0] = "Test1"; 
    a[1] = "Test2"; 
} 

int main() 
{ 
    std::array<std::string, 2> test; 
    populate(test); 
    // print ... 
} 
+2

Я бы также упомянул, что 'data_t()' утечка памяти, и выполнение 'delete [] p' в строковом литерале может вызвать проблемы –

+0

Но мне нужно освободить память? У меня утечка памяти с этим кодом? – wcale

+2

@wcale: ваш код даже не компилируется ... Но да, вы бы пропустили память, если это сработало, потому что вы теряете указатель, возвращаемый выражением 'new'. –

5

тест [0] содержит указатель на статическую строку "Test1", которая не может быть deall ocated. Используйте strcpy для копирования строк C.

+2

Да. Реальная проблема. Учитывая, что код, как утверждается, соблюдает, проблема пренебрежения размером из массива, вероятно, опечатка. – Bingo

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