2013-08-30 3 views
0

Я дал размер массива вручную, как показано ниже:Динамическое распределение памяти массив символов

int main(int argc, char *argv[]) 
{ 
    char buffer[1024]; 
    strcpy(buffer,argv[1]); 
    ... 
} 

Но если данные, передаваемые в аргументе превышает этот размер, он может создаст проблемы.

Это правильный способ выделения памяти динамически?

int main(int argc, char *argv[]) 
{ 
    int length; 
    char *buffer; 
    length = sizeof(argv[1]); //or strlen(argv[1])? 
    buffer = (char*)malloc(length*sizeof(char *)); 
    ... 
} 
+3

Вы работаете в C или C++? Если вы работаете на C++, использование 'malloc()', как правило, ошибочно (и raw 'char *' тоже не очень хорошая идея). Если вы работаете на C, вам не нужен тег C++. На самом деле, не дублируйте вопрос - это два разных языка. –

+0

Что касается вашего вопроса "use' sizeof() 'или' strlen() '", то использование 'strlen (argv [1]) + 1' будет работать так, как вы этого хотите (и использование' sizeof' будет вообще не выделяться достаточно Память). Большой вопрос: зачем нужна копия данных, на которые указывает 'argv [1]'? –

ответ

-1

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

length=sizeof(argv[1]) + 1; 

Тогда это должно быть в порядке.

+2

sizeof в этом контексте не в порядке – john

+0

@David Elliman Тип 'argv [1]' is 'char *'. 'sizeof (char *)' указывает размер указателя, а не длину строки, на которую указывает. – simonc

+0

Это правда, я читал его как strlen, который я видел весь день ... –

4

sizeof говорит вам размер char*. Вы хотите strlen вместо

if (argc < 2) { 
    printf("Error - insufficient arguments\n"); 
    return 1; 
} 
length=strlen(argv[1]); 
buffer = (char*)malloc(length+1); // cast required for C++ only 

Я предложил несколько других изменений здесь

  • вам нужно добавить дополнительные байты buffer для нулевого терминатора
  • вы должны проверить, что пользователь прошел в argv[1]
  • sizeof(char *) неверно при расчете хранения требуемого для строки. AC строка представляет собой массив char с так что вам нужно sizeof(char), который гарантированно будет 1, так что вам не нужно умножать на него

В качестве альтернативы, если вы работаете на Posix-совместимой системе, вам может упростить и использовать strdup вместо:

buffer = strdup(argv[1]); 

Наконец, убедитесь, что free эту память, когда вы закончите с этим

free(buffer); 
1
length= strlen(argv[1]) //not sizeof(argv[1]); 

и

//extra byte of space is to store Null character.  
buffer = (char*)malloc((length+1) * sizeof(char)); 

С sizeof(char) всегда один, вы также можете использовать это:

buffer = (char*)malloc(length+1);      
+1

Если C: листинг malloc не нужен, а 'sizeof (char)' также избыточен, потому что это '1'. – pzaenger

+0

@pzaenger да согласен, написан в общем виде. – Gangadhar

1

Правильный путь заключается в использовании std::string и пусть C++ сделать работу для вас

#include <string> 

int main() 
{ 
    std::string buffer = argv[1]; 
} 

, но если вы хотите сделать это трудный путь, то это правильно

int main() 
{ 
    int length = strlen(argv[1]); 
    char* buffer = (char*)malloc(length + 1); 
} 

Не забудьте указать +1 для нулевого терминатора, используемого в строках стиля С.

0

Во-первых, если вы используете C++, я думаю, что лучше использовать new вместо malloc.

Во-вторых, размер malloc равен false: buffer = malloc(sizeof(char) * length);, потому что вы выделяете буфер char, а не char * buffer.

В-третьих, вы должны выделить 1 байт больше для конца своей строки и сохранить '\ 0'.

Наконец, sizeof получает только размер типа, а не строку, вы должны использовать strlen для получения размера строки.

+0

В C++ еще лучше не использовать 'new', а использовать' std :: string'. –

+0

Я думаю, что это зависит от того, что вы хотите с ним сделать, если это для хранения строки, конечно std :: string выполняет задание, но для массива, который не является обязательным для строки, я предпочитаю управлять ею самостоятельно. – Hulor

1

В C++ вы можете сделать это, чтобы получить свои аргументы в хорошей структуре данных.

const std::vector<std::string>(argv, argv + argc)

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