簡體   English   中英

如何在C函數中使用雙指針分配內存?

[英]How to allocate memory using double pointers in a function in C?

我想知道如何在使用雙指針的函數中為char指針分配內存並寫入指針。

我試圖編寫以下代碼,但是崩潰了。 這是什么錯誤?

#include <stdio.h>
void myfunc(const char* src, char** dest)
{
  *dest = (char*)malloc(200);
  while(*(*dest++) = (*src++ != '\0'));
  *(*(++dest)) = '\0';
}
void main()
{
 char* src = "hello";
 char* dest = null;
 myfunc(src, &dest);
 printf("%s\n",dest);
}

您編寫了一個比較循環而不是復制循環(' == 'vs' = '),並且在編寫時增加了錯誤的指針:

 while(*(*dest++) == *src++);

(附加行:

 *(*(++dest)) = '\0';

是該問題的最新補充。 我不確定我是否想嘗試解析所有內容。 它不是解決問題的一部分。 請參閱下面的討論。)

最正確的方法可能是:

 char *tgt = *dest;
 while ((*tgt++ = *src++) != '\0')
     ;

我們可以分階段更正您的代碼(我這樣做是這樣的):

static void myfunc(const char* src, char** dest)
{
    *dest = (char *)malloc(200);
    char *tgt = *dest;
    while ((*(tgt++) = *(src++)) != '\0')
        ;
}

這會在循環中完全括上表達式。 現在,我們可以用*dest代替tgt

static void myfunc(const char* src, char** dest)
{
    *dest = (char *)malloc(200);
    char *tgt = *dest;
    while ((*((*dest)++) = *(src++)) != '\0')
        ;
    printf("1: %s\n", tgt);
}

並顯示1: hello ,但是主程序顯示空行,因為您已修改*dest因此它指向復制的字符串末尾的NUL '\\0' 因此,您需要執行以下操作:

static void myfunc(const char* src, char** dest)
{
    *dest = (char *)malloc(200);
    char *tgt = *dest;
    while ((*((*dest)++) = *(src++)) != '\0')
        ;
    printf("1: %s\n", tgt);
    *dest = tgt;
}

然后main()將打印正確的答案。 但是,如果您使用tgt (“ target”的縮寫;我通常將dst用作目標,但這太接近您的dest )了,那么您也可以避免在第一個*dest中增加*dest的復雜性地點。

實際上,您應該考慮使用:

#include <string.h>

...
strcpy(*dest, src);

復制字符串。 使用strcpy()可能更好,例如“更快”和“更簡單”,並且明確正確。


另外,您還應該具備:

#include <stdlib.h>

聲明malloc()

並且main()的正確返回類型是int

int main()
{
    ...
    return(0);
}

在C99中,返回值(很遺憾)是可選的,如果丟失,則假定為零(成功)。 這符合C ++ 98的行為。 在早期版本的C中,返回不是可選的。

這個小片段中有很多問題,我不知道從哪里開始...總結起來,您使代碼變得不必要地復雜,因此最終充滿了錯誤。

為了使此代碼可編譯而要解決的問題:

  • 除非這是用於嵌入式系統的代碼,或者除非您正在編寫操作系統,否則main必須返回int。
  • NULL是C中的大寫常量。可以在庫stddef.h中找到。
  • malloc函數位於stdlib.h中,必須包含在內。

嚴重的錯誤:

  • 永遠不要類型轉換malloc的結果。 C FAQ此SO帖子中有更多信息。
  • 始終釋放由malloc分配的內存。
  • 您將* src ++!='\\ 0'的布爾結果(true / false)分配給一個字符。

導致錯誤的廣為人知的不良和危險做法:

  • 始終將指向字符串文字的指針聲明為const。
  • 切勿在內部條件下使用分配。 (MISRA-C:2004 13.1)。
  • 切勿在復雜的表達式內使用++運算符(MISRA-C:2004 12.13)。
  • 切勿將分號放在包含循環語句的行的末尾。 (MISRA-C:2004 14.9)
  • 切勿使用任何沒有大括號{}的語句(MISRA-C:2004 14.8)。

風格差:

  • main()應該總是返回。
  • 避免使用“幻數”,尤其是在將參數傳遞給malloc時。
  • 始終檢查malloc()的結果。

有用的提示:

  • 與malloc不同,calloc會將所有分配的內存都設置為零。 如果您使用calloc,則不必手動將它們設置為零。

固定代碼:

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

#define DYNAMIC_BUF_SIZE 200

void make_string (const char* src, char** dest)
{
  *dest = calloc(DYNAMIC_BUF_SIZE, sizeof(char));

  if(*dest == NULL)
  {
    /* error handling here */
  }

  char* dst = *dest;
  *dst = *src;

  while(*src != '\0')
  {
    dst++;
    src++;
    *dst = *src;
  }
}

void delete_string (char* str)
{
  free(str);
}

int main()
{
  const char* src = "hello";
  char* dest = NULL;

  make_string (src, &dest);
  printf("%s\n",dest);
  delete_string(dest);

  return 0;
}

編輯: OP不要求strcpy()的新版本。

//It seems that you don't understand the nature of char* and char**.
char *str = "hello! I am from China and i want to make friends with foreigners";
char **ptr = {"hello!","i want to learn spoken English","sinalym@163.com"};
//Allocate memory for a char** variable. Two steps as follows:
int length[3] = {6,31,16};
char **ptr2 = new char*[3];
for(int i = 0;i < length[i];i++)
    *(ptr2 + i) = new char [length[i]];
//delete according to a reverse order.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM