将字符串复制到动态二维数组中

时间:2014-12-29 15:30:41

标签: c arrays memory dynamic

就像标题已经说明我想将各种字符串复制到二维数组中。每个字符串都有不同的大小,因此我需要使用内存重新分配。下面的代码应该做这个工作,但不知怎的,我不能让它工作。

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

int main(void) {

char **str = NULL;
int str_num = 1;

// get string
char *str_new = "hey mate\0";

printf("%s\n",str_new);

// reallocation for str_new
str = realloc(str,str_num*sizeof(char));
str[str_num-1] = realloc(str,strlen(str_new));

// copy string to new space
strcpy(*str, str_new);

// displaying string
printf("%s\n",str[str_num-1]);


return EXIT_SUCCESS;

}

4 个答案:

答案 0 :(得分:4)

重新分配存在一个问题:

str = realloc(str,str_num*sizeof(char));

您只为单个字节分配空间,而不是为char指针。这是undefined behavior

改为例如

str = realloc(str,str_num*sizeof(char*));

另一个问题,也是未定义行为的原因是实际的字符串分配:

str[str_num-1] = realloc(str,strlen(str_new));

您要重新分配 str 而不是str[0]你没有为字符串终结符分配空间。

对于这个,根本不使用realloc,因为您只需要分配一次,只需要malloc,或者只使用strdup功能在一次通话中同时进行分配和复制:

str[str_num - 1] = strdup(str_new);

顺便说一句,当使用realloc永远不会分配给您作为第一个参数传入的同一个指针时,因为如果realloc函数失败,它将返回NULL并且你会松开原来的指针。而是分配给临时指针,如果它是非空的,则分配给实际的指针。

答案 1 :(得分:1)

除了纠正(如Joachim Pileborg's answer中所示)

str = realloc(str,str_num*sizeof(char));  

str = realloc(str,str_num*sizeof(*str));

你应该注意,传递给realloc的指针必须是任何malloc族函数返回的指针,否则它指向NULL。你可以这样做

str[str_num-1] = NULL;
str[str_num-1] = realloc(str[str_num-1], strlen(str_new)+1);

答案 2 :(得分:1)

char **str = malloc(sizeof(char *) * n); /* n= number of pointers */

首先为指针分配内存,然后将内存分配给单个指针,如

   for(i=0;i<n;i++)
   {
       str[i] = malloc(sizeof(char) * 20);
       /* copy your string to the allocated memory location here*/
   }

否则你可以拥有

char **str = NULL;

str = realloc(str,str_num * sizeof(char *));

答案 3 :(得分:1)

我认为你不明白realloc是做什么的,你发布的代码不对,代码应该这样编写

char **str = NULL;
int str_num = 1;

// get string
char *str_new = "hey mate\0";

printf("%s\n",str_new);

/*
    // reallocation for str_new
    str = realloc(str, str_num * sizeof(char));
 */ 
/* allocate space for `str_num` pointers of char */
str = malloc(str_num * sizeof(char *));
if (str == NULL) /* check it worked */
    return -1;

/* allocate space for the number of characters in str_new and
 * the termination null byte 
 */
str[str_num - 1] = malloc(1 + strlen(str_new));
if (str[str_num - 1] == NULL)
{
    free(str);
    return -1;
}
/*
 * // copy string to new space
 * strcpy(*str, str_new);
 */
/* use the same index since if str_num > 1 the above is wrong */
strcpy(str[str_num - 1], str_new);

// displaying string
printf("%s\n",str[str_num - 1]);

应该像这样使用realloc

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

int main(void) 
{
    char **str = NULL;
    int str_num;
    // get string
    char *str_new[2] = {"hey mate 1", "hey mate 2"};

    for (str_num = 0 ; str_num < 2 ; ++str_num)
    {
        char **pointer;
        printf("%s\n", str_new[str_num]);
        /*
            // reallocation for str_new
            str = realloc(str, str_num * sizeof(char));
         */ 

        /* re-allocate space for `str_num` pointers of char */
        pointer = realloc(str, (1 + str_num) * sizeof(char *));
        /* 
         * If you use
         * 
         *      str = realloc(str, str_num * sizeof(char *));
         * 
         * you wont be able to free(str) on failure
         */
        if (pointer == NULL)
        {
            int j;
            /* on failure cleanup and return */
            for (j = str_num - 1 ; j >= 0 ; --j)
                free(str[j]);
            free(str);

            return -1;
        }
        str = pointer;      

        /* allocate space for the number of characters in str_new and
         * the termination null byte 
         */
        str[str_num] = malloc(1 + strlen(str_new[str_num]));
        if (str[str_num] == NULL)
        {
            free(str);
            return -1;
        }
        /*
         * // copy string to new space
         * strcpy(*str, str_new);
         */
        /* use the same index since if str_num > 1 the above is wrong */
        strcpy(str[str_num], str_new[str_num]);

        // displaying string
        printf("%s\n",str[str_num]);
    }

    return EXIT_SUCCESS;
}

你应该记得free所有分配的内存。

此外,您不需要将'\0'嵌入到字符串文字中。