2013-09-28 3 views
18

Я пытаюсь написать программу, которая читает в последовательности строк из текстового файла и хранит их в массиве строк, динамически выделяя память для каждого элемента. Мой план состоял в том, чтобы хранить каждую строку в массиве с помощью указателя, а затем увеличивать размер массива по мере того, как читалось больше. Мне трудно понять, почему мой тестовый код ниже не работает. Является ли это приемлемой идеей?Динамическое распределение памяти для массивов указателей

char *aPtr; 
aPtr =(char*)malloc(sizeof(char)); 

aPtr[0]="This is a test"; 


printf("%s",aPtr[0]); 
+1

Это не работает, потому что вы используете пространство 'malloc' для одного символа, а затем пытаетесь присвоить целую строку символу l char. –

+0

Рекомендуемое чтение: [Когда следует использовать malloc в C, а когда нет?] (Http://stackoverflow.com/a/1963812/2455888). – haccks

ответ

15

В C строка - это char*. Динамический массив типа T представлен в виде указателя на T, поэтому для char* это будет char**, а не просто char* способом, которым вы его объявили.

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

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

char **aPtr; 
int len = 1; // Start with 1 string 
aPtr = malloc(sizeof(char*) * len); // Do not cast malloc in C 
aPtr[0] = "This is a test"; 
printf("%s",aPtr[0]); // This should work now. 
+0

Чтобы проверить (пожалуйста, примите меня, я новичок =]), если вы хотите, чтобы динамический массив указателей указывал на символ (например, по мере необходимости в приложении, где вам может понадобиться хранить строки символов с переменными номерами, например, из чтение текстового файла без знания его длины или сбор пользовательского ввода неопределенной длины), тогда вам понадобится динамический массив Char *, и вам понадобится Char **. Символ ** может указывать на разные указатели на символы, которые могут быть начальным адресом для разных строк символов. –

+0

Что такое 'len = 1' здесь? Похоже, что «Это тест» будет 14 символов, каждый из которых является байтом ... но этот код не упоминает 14, и он не выполняется при запуске. – nmz787

+0

@ nmz787 Обратите внимание на тип 'aPtr', это двунаправленный указатель, поэтому представляет собой массив указателей на символы. Затем указатель char устанавливается в нуль элемента; в этом коде нет строкового копирования. – dasblinkenlight

5
char * aPtr; 

как указатель на символ, к которому выделяется память для хранения точно 1 характер.

Ведение

aPrt[0] = "test"; 

Вы обращаетесь к памяти для этого один символов и попытаться сохранить адрес буквального "test" к нему. Это не удастся, так как этот адрес больше всего шире, чем персонаж.

Исправление вашего кода было бы выделение памяти для указателя на символ.

char ** aPtr = malloc(sizeof(char *)); 
aPtr[0] = "test"; 
printf("%s", aPtr[0]); 

ли более элегантный и более более надежный подход было бы выделить такой же (а также добавление обязательной проверки ошибок), выполнив:

char ** aPtr = malloc(sizeof *aPtr); 
if (NULL == aPtr) 
{ 
    perror("malloc() failed"); 
    exit(EXIT_FAILURE); 
} 

... 
9
char *str; //single pointer 

При этом вы можете хранить один строка.


Для хранения array of strings вам нужно two dimensional character array

или еще array of character pointers или еще double pointer


char str[10][50]; //two dimensional character array 

Если вы объявляете, как это вам не нужно выделять память, поскольку это статическое объявление


char *str[10]; //array of pointers 

Здесь нужно выделить память для каждого указателя

петли через массив для выделения памяти для каждого указателя

for(i=0;i<10;i++) 
str[i]=malloc(SIZE); 

char **str; //double pointer 

Здесь нужно выделить память для Количества указатели, а затем выделяют память для каждого указателя.

str=malloc(sizeof(char *)*10); 

А затем цикл через массив выделения памяти для каждого указателя

for(i=0;i<10;i++) 
str[i]=malloc(SIZE); 
-1

Вы делаете это совершенно неправильно. Правильная версия вашего кода должна быть такой:

int main() 
{ 
char *aPtr; 
aPtr =(char*)malloc(20*sizeof(char)); 
aPtr ="This is a test"; 
printf("%s",aPtr); 
} 

Вы можете использовать массив указателей. если вы хотите сохранить несколько строк. Да, я знаю, что использовать цикл for будет легко. Но я пытаюсь объяснить простым способом, даже новичок может понять.

int main() 
{ 
char *aPtr[10]; 
aPtr[0] =(char*)malloc(20*sizeof(char)); 
aPtr[0] ="This is a test"; 
aPtr[1] =(char*)malloc(20*sizeof(char)); 
aPtr[1] ="This is a test2"; 
printf("%s\n%s\n",aPtr[0],aPtr[1]); 
} 
+0

Ваш первый пример утечки памяти, а именно 20 байт. Выполнение 'aPtr =" Это тест ";' вы теряете ссылку на возвращаемый 'malloc()'. Эта память никогда не использовалась и никогда не будет использоваться во время работы программы. – alk

+0

'sizeof (char)' is '1' быть defintion. Выдача результата «malloc/calloc/realloc» не обязательно в C и не рекомендуется: http://stackoverflow.com/a/605858/694576 – alk

+0

Спасибо всем, кто ответил, что это отличная помощь – user2826534

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