如何在C中为字符串分配动态存储区

问题描述 投票:0回答:6

为什么此代码不起作用?我一直在尝试使用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] != '\0')
    {
    i = i + 1;
    printf("%s\n\t", str);
    }
    return(0);
}
c memory-management malloc command-line-arguments c-strings
6个回答
1
投票

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 '\0' 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;
}

1
投票
  • 以标准化方式命名main()的参数:int argc, char *argv[]
  • (请注意,argv[0]是可执行文件的名称,您可能感兴趣,也可能不感兴趣)
  • 首先,您需要分配argc个字符指针。如果对您的程序有意义,可以选择在末尾使用NULL标记值-请勿将其与null终止相混淆。
  • 因此,您宁可使用char** str_table = malloc(sizeof(*str_table) * argc);之类的东西>
  • 对于str_table中的每个项目,请为strlen(argv[i]) + 1字符(实际数据)分配额外的内存。在这种情况下,+ 1表示无效终止,这是强制性的。
  • [strcpyargv[i]到您自己的数组。

str = malloc(sizeof(char) * (ac + 1));一定不是您想要的,因为您说的是str的大小是char的大小乘以命令行中的参数数目加1,因此,如果您有2个参数,字符串只能有3个字符的空间。

ac不代表用户输入的长度(因为您一直试图为ac+1分配内存)+ str指向没有任何有效数据的原始内存位置,即使您想使用[ C0]然后:

ac

如果您试图在堆栈上分配内存,则可能还会寻找VLA。

此声明

#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,'\0',ac+1);  //added for NULL termination
    }

    return(0); 
}

没有意义。

此外,分配的数组未初始化。所以这条语句

str = malloc(sizeof(char) * (ac + 1));

导致未定义的行为。

似乎您想要做的是通过将命令行参数复制到动态分配的数组中来输出命令行参数。

如果是这样,程序可以按照以下方式查看

if(str[i] != '\0')

如果要运行该程序,例如

#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 ac包含参数。

例如:char **av./program arg1 arg2将是“ ./程序”av[0]将为“ arg1”av[1]将是“ arg2”av[2]将是“ a”

现在,如果您只想要第一个参数的大小,则可以使用strlen():av[2][0]

您需要而不是if语句的是while循环来遍历av的所有元素。例如:

int size = strlen(av[1]);

0
投票

str = malloc(sizeof(char) * (ac + 1));一定不是您想要的,因为您说的是str的大小是char的大小乘以命令行中的参数数目加1,因此,如果您有2个参数,字符串只能有3个字符的空间。


0
投票

ac不代表用户输入的长度(因为您一直试图为ac+1分配内存)+ str指向没有任何有效数据的原始内存位置,即使您想使用[ C0]然后:


0
投票

此声明


0
投票

您的代码中存在逻辑错误。

Hello World 是参数的数量。int ac包含参数。

© www.soinside.com 2019 - 2024. All rights reserved.