C 程序使用 char** 在变量字符串列表上执行 malloc 和 free

问题描述

要在 C 中分配和释放单个字符串,我执行以下操作:

char[10] stringTocopy = "copyString";
int length = strlen(stringTocopy) + 1;
char* copiedString = malloc(length);
strcpy(copiedString,stringTocopy,length);
printf("DatabasePath=%s\r\n",copiedString);
free(copiedString);

在我的程序中,我需要将此类字符串复制到 char** 数据类型。我需要帮助来编写这样的程序。我正在使用第三方 API,该 API 的结构包含此 char** 字段条目。

我不知道如何为该数据类型分配内存,然后将copiedString复制到此类值的列表中。以及如何在使用后释放价值。

解决方法

分配内存:

char **arr = malloc(r * sizeof(char *)); 
for (i=0; i<r; i++)
{        
  arr[i] = malloc(c * sizeof(char)); 
}

释放内存:

for (i=0; i<r; i++)
{        
   free(arr[i]); 
}
free(arr);
,

我不知道如何为这种数据类型分配内存......

Follows 是用于分配的有用 C 习语。

size_t number_in_array =  ...;
ptr = malloc(sizeof *ptr * number_in_array);
if (ptr == NULL) {
  puts("Allocation failed");
} else {
  puts("Success");
  // Use ptr
  free(ptr):  // **
}
...
free(ptr): // **
// ** free(ptr) in 1 of 2 places.

请注意,不需要需要对分配中的指针类型进行编码:ptr = malloc(sizeof *ptr * number_in_array);。与尝试对类型进行编码相比,这更容易正确编码、审查和维护。


...然后将 CopiedString 复制到此类值的列表中。

您已经有很好的代码来形成复制的字符串。做一个辅助函数。下面是一些改进的 OP。还要研究常见的 strdup() 函数。

char *my_strdup(const char *stringToCopy) {
  size_t size = strlen(stringToCopy) + 1;
  char* CopiedString = malloc(size);
  if (CopiedString) {
    memcpy(CopiedString,stringToCopy,size);
  }
  return CopiedString;
}

以及如何在使用后释放价值。

size_t number_in_array = 3;
char **ptr = malloc(sizeof *ptr * number_in_array);
if (ptr == NULL) {
  puts("Allocation failed");
} else {
  ptr[0] = my_strdup("Hello");
  ptr[1] = my_strdup(" ");
  ptr[2] = my_strdup("World");
  // Use ptr (could check for ptr[] allocation failures first)
  for (size_t i = 0; i < number_in_array; i++) {
    free(ptr[i]);
  }
  free(ptr):
}
,

您可以使用 strdup 在 c 中创建 malloced 字符串。

char ** presult = NULL;

对于双指针“presult”,我们可以像这样分配数据。

    if (presult) {
        *presult = strdup("CopyString");
    }

示例代码:

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

    int copy_data(char ** p) {
       if (p) {
           *p = strdup("Test data");
       }
       return 0;
    }

    int main () {
       char * p = NULL;
       copy_data(&p);
       if (p) {
           printf("daat : %s\n",p);
           // free if not used
           free(p);
           p = NULL;
       }
       return 0;
    }
,

完成以下程序,该程序解释了如何为 char** 分配内存以及如何free 相同。

评论是为了理解,如果需要澄清,请回复。

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

#define NUMBER_OF_STRINGS 5
#define MAX_LEN_OF_STRING 50

void printStrings_array(char ex_strings[][MAX_LEN_OF_STRING],int nstrings);
char** allocMemForStrings(int nStrings);
void printStrings_ptr(char** strings,int nStrings);

int main()
{

    // example list of string for which we are going to allocate memory and store in char**
    char ex_strings[NUMBER_OF_STRINGS][MAX_LEN_OF_STRING] = 
                                                {
                                                "This is the First String","This is the Second String","This is the Third String","This is the Fourth String","This is the Fifth String",};
    
    printf("contents of char[][] \n");
    printStrings_array(ex_strings,NUMBER_OF_STRINGS);

    // list_of_strings is a variable which points to list of strings
    char** list_of_strings = NULL;

    // allocating memory for list of strings
    if ( list_of_strings = allocMemForStrings(NUMBER_OF_STRINGS))
    {
        int i = 0;
        printf("got %p for list_of_strings\n",(void*)list_of_strings);
        while(i < NUMBER_OF_STRINGS)
        {
            size_t len = strlen(ex_strings[i])+1;
            
            // allocate memory for each string as per its length
            list_of_strings[i] = malloc(len);
            printf("got %p for string %d\n",(void*)list_of_strings[i],i);
            memset(list_of_strings[i],len);
            strncpy(list_of_strings[i],ex_strings[i],len);
            i++;
        }
        printf("contents of char** \n");
        printStrings_ptr(list_of_strings,NUMBER_OF_STRINGS);
        
        // free ing the memory for char **
        // first we need to free the memory for each of the strings pointed by the list_of_strings variable.
        i = 0;
        while(i < NUMBER_OF_STRINGS)
        {
            printf("\n freeing %p ",(void*)list_of_strings[i]);
            free(list_of_strings[i]);
            list_of_strings[i] = NULL;
            i++;
        }
        //now free the list_of_strings pointer 
        printf("\n finally freeing %p ",(void*)list_of_strings);
        free(list_of_strings);
        // to avoid dangling pointers,its best practice to set the pointers = NULL after free.
        list_of_strings = NULL;
        
    }
    else
    {
        printf("cannot allocate memory for strings\n");
    }
    return 0;
}

void printStrings_array(char ex_strings[][MAX_LEN_OF_STRING],int nstrings)
{
    for(int i = 0; i< nstrings;i++)
        printf(" %s\n",ex_strings[i]);
}

void printStrings_ptr(char** strings,int nStrings)
{
    for(int i = 0; i< nStrings;i++)
        printf(" %s\n",strings[i]);

}

char** allocMemForStrings(int nStrings)
{
     // need to have memory to store nStrings
     return malloc(nStrings * sizeof (char*));
}