如何在C中为字符串分配动态内存区
How to allocate a dynamic memory zone for a character string in C
为什么这段代码不起作用?我一直在尝试做的是使用 int main(int ac, char ** ac)
和 malloc()
.
为数组的未知用户输入长度进行动态分配
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av)
{
char *str;
int i;
str = malloc(sizeof(char) * (ac + 1));
i = 0;
if(str[i] != '[=10=]')
{
i = i + 1;
printf("%s\n\t", str);
}
return(0);
}
ac
不代表用户输入长度(因为您一直在尝试为 ac+1
分配内存)+ str
指向没有任何有效数据的原始内存位置,即使那样,如果您想使用 ac
那么:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //added for memset
int main(int ac, char **av)
{
char *str;
int i; //USELESS
str = malloc(sizeof(char) * (ac + 1)); //str points to a memory (if allocated) which contains garbage
i = 0; //NO USE
if(str) //checks if memory has been allocated - NO INCREMENT NEEDED OR VALID
{
printf("Memory has been successfully allocated");
memset(str,'[=10=]',ac+1); //added for NULL termination
}
return(0);
}
如果您尝试在堆栈上分配内存,您还可以查找 VLA。
- 以标准化方式命名 main() 的参数:
int argc, char *argv[]
.
- (注意
argv[0]
是可执行文件的名称,您可能感兴趣也可能不感兴趣)
- 首先你需要分配
argc
个指向字符的指针。如果这对您的程序有意义,则可以选择在末尾使用 NULL 标记值 - 不过不要将其与空终止混淆。
- 所以你应该有类似
char** str_table = malloc(sizeof(*str_table) * argc);
的东西
- 对于
str_table
中的每个项目,为 strlen(argv[i]) + 1
个字符分配额外的内存,即实际数据。在这种情况下,+1 用于空终止,它是强制性的。
strcpy
从 argv[i]
到你自己的数组。
ac 不是任何参数的长度,而是参数计数。
当用户指定一个参数时,这将始终为 2.
如果程序只输出第一个参数,你可以这样做:
#include <stdio.h>
int main(int argc, char **argv) {
if(argc == 2)
printf("%s\n", argv[1]);
return 0;
}
如果您想将参数加载到字符串中,您必须获取它的长度。
例如,这可以通过 strlen() 函数完成:
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for malloc and free */
#include <string.h> /* for strlen and strcpy */
int main(int argc, char **argv) {
if(argc == 2) {
char *input_string;
int input_string_length;
input_string_length = strlen(argv[1]);
/* strlen() does not include the '[=11=]' in the length */
input_string = malloc((input_string_length + 1) * sizeof(char));
strcpy(input_string, argv[1]);
printf("%s\n", input_string);
free(input_string);
}
return 0;
}
您的代码中存在一些逻辑错误。
int ac
是参数个数。
char **av
包含参数。
例如:./program arg1 arg2
av[0]
将是“./program”
av[1]
将是 "arg1"
av[2]
将是 "arg2"
av[2][0]
将是 "a"
现在,如果您只想要第一个参数的大小,您可以使用 strlen() :
int size = strlen(av[1]);
你需要的不是 if 语句,而是一个 while 循环来遍历 av 的所有元素。
例如:
int i = 0;
while (i <= ac) {
printf("%s", av[i]);
...Your code...
i++;
}
此声明
str = malloc(sizeof(char) * (ac + 1));
没有意义。
而且分配的数组没有初始化。所以这个声明
if(str[i] != '[=11=]')
导致未定义的行为。
看来您要做的是通过将命令行参数复制到动态分配的数组中来输出命令行参数。
如果是这样,程序可以如下所示
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( int argc, char * argv[] )
{
if ( argc > 1 )
{
char **s = malloc( ( argc - 1 ) * sizeof( char *) );
for ( int i = 0; i < argc - 1; i++ )
{
s[i] = malloc( strlen( argv[i+1] ) + 1 );
strcpy( s[i], argv[i+1] );
}
for ( int i = 0; i < argc - 1; i++ )
{
puts( s[i] );
}
for ( int i = 0; i < argc - 1; i++ ) free( s[i] );
free( s );
}
return 0;
}
如果以运行程序为例
program Hello World
那么输出将是
Hello
World
您可以将自己的检查添加到内存分配是否成功的程序中。
为什么这段代码不起作用?我一直在尝试做的是使用 int main(int ac, char ** ac)
和 malloc()
.
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av)
{
char *str;
int i;
str = malloc(sizeof(char) * (ac + 1));
i = 0;
if(str[i] != '[=10=]')
{
i = i + 1;
printf("%s\n\t", str);
}
return(0);
}
ac
不代表用户输入长度(因为您一直在尝试为 ac+1
分配内存)+ str
指向没有任何有效数据的原始内存位置,即使那样,如果您想使用 ac
那么:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //added for memset
int main(int ac, char **av)
{
char *str;
int i; //USELESS
str = malloc(sizeof(char) * (ac + 1)); //str points to a memory (if allocated) which contains garbage
i = 0; //NO USE
if(str) //checks if memory has been allocated - NO INCREMENT NEEDED OR VALID
{
printf("Memory has been successfully allocated");
memset(str,'[=10=]',ac+1); //added for NULL termination
}
return(0);
}
如果您尝试在堆栈上分配内存,您还可以查找 VLA。
- 以标准化方式命名 main() 的参数:
int argc, char *argv[]
. - (注意
argv[0]
是可执行文件的名称,您可能感兴趣也可能不感兴趣) - 首先你需要分配
argc
个指向字符的指针。如果这对您的程序有意义,则可以选择在末尾使用 NULL 标记值 - 不过不要将其与空终止混淆。 - 所以你应该有类似
char** str_table = malloc(sizeof(*str_table) * argc);
的东西
- 对于
str_table
中的每个项目,为strlen(argv[i]) + 1
个字符分配额外的内存,即实际数据。在这种情况下,+1 用于空终止,它是强制性的。 strcpy
从argv[i]
到你自己的数组。
ac 不是任何参数的长度,而是参数计数。 当用户指定一个参数时,这将始终为 2.
如果程序只输出第一个参数,你可以这样做:
#include <stdio.h>
int main(int argc, char **argv) {
if(argc == 2)
printf("%s\n", argv[1]);
return 0;
}
如果您想将参数加载到字符串中,您必须获取它的长度。 例如,这可以通过 strlen() 函数完成:
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for malloc and free */
#include <string.h> /* for strlen and strcpy */
int main(int argc, char **argv) {
if(argc == 2) {
char *input_string;
int input_string_length;
input_string_length = strlen(argv[1]);
/* strlen() does not include the '[=11=]' in the length */
input_string = malloc((input_string_length + 1) * sizeof(char));
strcpy(input_string, argv[1]);
printf("%s\n", input_string);
free(input_string);
}
return 0;
}
您的代码中存在一些逻辑错误。
int ac
是参数个数。
char **av
包含参数。
例如:./program arg1 arg2
av[0]
将是“./program”
av[1]
将是 "arg1"
av[2]
将是 "arg2"
av[2][0]
将是 "a"
现在,如果您只想要第一个参数的大小,您可以使用 strlen() :
int size = strlen(av[1]);
你需要的不是 if 语句,而是一个 while 循环来遍历 av 的所有元素。 例如:
int i = 0;
while (i <= ac) {
printf("%s", av[i]);
...Your code...
i++;
}
此声明
str = malloc(sizeof(char) * (ac + 1));
没有意义。
而且分配的数组没有初始化。所以这个声明
if(str[i] != '[=11=]')
导致未定义的行为。
看来您要做的是通过将命令行参数复制到动态分配的数组中来输出命令行参数。
如果是这样,程序可以如下所示
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( int argc, char * argv[] )
{
if ( argc > 1 )
{
char **s = malloc( ( argc - 1 ) * sizeof( char *) );
for ( int i = 0; i < argc - 1; i++ )
{
s[i] = malloc( strlen( argv[i+1] ) + 1 );
strcpy( s[i], argv[i+1] );
}
for ( int i = 0; i < argc - 1; i++ )
{
puts( s[i] );
}
for ( int i = 0; i < argc - 1; i++ ) free( s[i] );
free( s );
}
return 0;
}
如果以运行程序为例
program Hello World
那么输出将是
Hello
World
您可以将自己的检查添加到内存分配是否成功的程序中。