2012-03-16 11 views
0

ダブルポインタを使って関数内のcharポインタのメモリをどのようにして、ポインタに書き込むかを知りたい。Cの関数でダブルポインタを使用してメモリを割り当てる方法は?

次のコードを書き込もうとしましたが、クラッシュします。これのバグは何ですか?

#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); 
} 
+0

「dest」にはデータがありません。最初に有効なデータを入力し、それがヌルで終了していることを確認してから、 '=='操作を行います。 – Mahesh

+0

あなたは何を達成しようとしていますか?あなたが境界チェックをしないで各文字を比較しようとしているように見えますし、 'malloc'した後に決して何にも' dest'を設定することはありません。 – Joe

+1

'char **'をインクリメントすると、次の 'char *'を指し示し、次の 'char'は指しません。 – sidyll

答えて

3

あなたは代わりにコピーループ(「== 『VS』 =」)のループを比較書いた、とあなたが書く間違ったポインタインクリメントされています

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

(追加しますライン:

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

が質問にする最新追加され、私は私がすべてであること解析してみたいかわからないことが問題の解決策の一部ではありませんDを参照してください。。。以下iscussion)

それが正しい取得する最も簡単な方法は、おそらくです:。

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') 
     ; 
} 

この括弧のループの表現は完全に。

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'を指しているので、メインプログラムは、空行を出力します。私たちは今、 tgtため *destを置き換えることができます。だから、あなたは何をする必要があるでしょう:

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を増やす複雑さを避けることができます。

実際には、あなたが使用することを検討すべきである:

#include <string.h> 

... 
strcpy(*dest, src); 

は、文字列をコピーします。 strcpy()を使用すると、「より速く」「より簡単に」正確に正しいと思われます。


また、あなたが持っている必要があります。

#include <stdlib.h> 

malloc()を宣言します。

そしてmain()の正しい戻り値の型はint次のとおりです。

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

それが欠落している場合、リターンです(残念)オプションとゼロ(成功)が仮定されます。これはC++ 98の動作に適合します。以前のバージョンのCでは、リターンはオプションではありませんでした。

+0

私はstrcpyなしでコピーする方法を知りたい。同じ機能と理解のためのexplinationで。 – user1274081

0

この小さなスニペットには非常に多くの問題があります。私はどこから始めるべきかわかりません。要約すれば、コードは不必要に複雑になり、バグがいっぱいになります。これは、組込みシステムのためのコードである、またはあなたが手術 システムを書いているのでない限り、メインがintを返す必要がない限り

  • :このコードのコンパイルをするために修正する

    物事。

  • NULLはCの大文字の定数です。ライブラリstddef.hにあります。
  • malloc関数は、stdlib.hに含まれていなければなりません。

重大なバグ:

  • は、malloc関数の結果を型キャストしないでください。 C FAQおよびthis SO postの詳細情報
  • 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)。

悪いスタイル:

  • メイン()常に返す必要があります。
  • 特に、mallocにパラメータを渡すときは、「マジックナンバー」を避けてください。
  • 常にmalloc()の結果を確認してください。

便利なヒント:

  • のcalloc malloc関数とは異なり、ゼロに割り当てられたメモリのすべてを設定します。 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; 
} 

EDIT:strcpyのなし新バージョン()、OPによって要求されます。

0
//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","[email protected]"}; 
//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. 
関連する問題