使用malloc在C中为字符串分配内存

时间:2019-01-07 18:07:22

标签: c string malloc

我正在尝试使用malloc为字符串数组分配内存。在用户输入之前,每个字符串的大小都不知道,因此这就是我尝试为数组中的每个元素分配内存的方法。

我的代码有一些错误,但无法弄清楚或无法理解。我在分配时遇到错误。谁能告诉我这是怎么了?

bool read_strings(char * strings[], int n) 
{
    int i = 0;
    while (i<n)
    {
        char string[MAX_LENGTH];
        if (scanf("%s", string)!=1)
            return false;
        char* memory= (char*)malloc(sizeof(char)*strlen(string));
        if (memory == NULL)
            return false;
        memory = string;
        strings[i] = memory;
        i++;
    }
    return true;
}

非常感谢!

5 个答案:

答案 0 :(得分:2)

至少您必须替换

char* memory= (char*)malloc(sizeof(char)*strlen(string));
if (memory == NULL)
    return false;
memory = string;
strings[i] = memory;

作者

strings[i] = strdup(string)

请注意,使用scanf("%s", string)读取的字符串之间的分隔符是空格

答案 1 :(得分:0)

您有很多错误

  1. (char*)malloc(sizeof(char)*(strlen(string) **+ 1**))。您必须为'\0'
  2. 保留内存
  3. 非常错误

    memory = string;

    要复制字符串,您必须使用usr strcpy(当今正确的功能是strncpy更安全)

答案 2 :(得分:0)

问题就在这里

char* memory = (char*)malloc(sizeof(char)*strlen(string));
memory = string; <<<
strings[i] = memory;

如果将字符串分配给指针,则会丢失内存。

要么:

a)使用strcpy()或strncpy()将字符串复制到新分配的内存中,并确保您有足够的空间容纳NULL字符\0

strings[i] = (char*)malloc(sizeof(char) * (strlen(string) + 1));
strcpy(strings[i], string);

b)使用strdup(),就像strcpy()和malloc()之间的混合,它为字符串创建了足够的空间并将其复制到新的内存位置

 strings[i] = strdup(string);

答案 3 :(得分:0)

要在C中拥有真正无限的缓冲区(或受内存和size_t的限制),可以逐步建立内存分配。

#include <stdlib.h>  /* realloc free */
#include <stdio.h>   /* stdin fgets printf */
#include <string.h>  /* strcpy */
#include <assert.h>  /* assert */
#include <stdint.h>  /* C99 SIZE_MAX */
#include <stdbool.h> /* C99 bool */

/* Returns an entire line or a null pointer, in which case eof or errno may be
 set. If not-null, it must be freed. */
static char *line(void) {
    char temp[1024] = "", *str = 0, *str_new;
    size_t temp_len, str_len = 0;
    while(fgets(temp, sizeof temp, stdin)) {
        /* Count the chars in temp. */
        temp_len = strlen(temp);
        assert(temp_len > 0 && temp_len < sizeof temp);
        /* Allocate bigger buffer. */
        if(!(str_new = realloc(str, str_len + temp_len + 1)))
            { free(str); return 0; }
        str = str_new;
        /* Copy the chars into str. */
        strcpy(str + str_len, temp);
        assert(str_len < SIZE_MAX - temp_len); /* SIZE_MAX >= 65535 */
        str_len += temp_len;
        /* If on end of line. */
        if(temp_len < sizeof temp - 1 || str[str_len - 1] == '\n') break;
    }
    return str;
}

static bool read_strings(char * strings[], int n) {
    char *a;
    int i = 0;
    while(i < n) {
        if(!(a = line())) return false;
        strings[i++] = a;
    }
    return true;
}

int main(void) {
    char *strings[4] = { 0 }; /* C99 */
    size_t i;
    bool success = false;
    do {
        if(!read_strings(strings, sizeof strings / sizeof *strings)) break;
        for(i = 0; i < sizeof strings / sizeof *strings; i++)
            printf("%lu: <%s>\n", (unsigned long)i, strings[i]);
        success = true;
    } while(0); {
        for(i = 0; i < sizeof strings / sizeof *strings; i++)
            free(strings[i]);
    }
    return success ? EXIT_SUCCESS : (perror("stdin"), EXIT_FAILURE);
}

我认为这是正确的。但是,这应该带来暂停;如果他们从不回车怎么办?如果您有一个MAX_LENGTH,那么请根据您的情况考虑静态分配。

编辑:它也有一个最坏情况下的运行时间,这可能是不希望的;如果要输入非常大的线条,请使用几何级数来分配空间。

答案 4 :(得分:-1)

我认为这是您想要做的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int read_strings(char * strings[], int n)
{
    int i = 0;
    char buffer[256] ={0}; /*a temp buffer of fixed max size for input */
    if(NULL == strings)
    {
        return 0 ;
    }

    for (i= 0; i<n; ++i)
    {
      if (fgets(buffer, 256,stdin)== NULL) /*safer then scanf - read input into the buffer*/
        return 0;
        strings[i]= malloc(sizeof(char)*(strlen(buffer)+1)); /* the char poiner in he i place will now point to the newly allocated memory*/
        strcpy(strings[i], buffer); /*copy the new string into the allocated memory now string[i] is pointing to a string*/
    }

return 1;
}
static void printStringsArray(const char* strArr[], size_t size)
{
    int i = 0;
    if(NULL == strArr)
    {
        return;
    }
    for(i = 0; i< size; ++i)
    {
        printf("%s", strArr[i]);
    }

}

 int main(void)
 {
    char * arr[3]; /*array of (char*) each will point to a string after sending it to the function */
    read_strings(arr,3);

    printStringsArray(arr,3);
    return 0;
 }