c
  • malloc
  • 2017-02-08 13 views 0 likes 
    0

    私はちょうど、PHPから来て、Cの学習を始めました。私はmallocとフリーを使う方法はまだ分かりません。ダイナミックメモリ割り当てにmallocとfreeを使用する方法

    1)私は "無料"を置くことができる以下の例のコードでは?

    #include <stdio.h> 
    #include <stdlib.h> 
    
    int strLen(char* text) { 
        int c = 0; 
        for (int i = 0; text[i] != '\0'; ++i) ++c; 
        return c; 
    } 
    
    
    char* reverse(char* text) { 
    
        int count = strLen(text); 
        char* t = malloc(count); 
    
        for (int i = count; i > 0; --i) { t[count - i] = text[i-1]; } 
        t[count] = '\0'; /* Add end of string */ 
    
        return t; 
    
    } 
    
    
    int main (int argc, char** argv) { 
    
        if (argc > 1) { 
        for (int i = 1; i < argc; ++i) { 
         printf("%d\t%s\t%s\n", i, argv[i], reverse(argv[i])); 
        } 
        } 
    
        return 0; 
    } 
    

    2)これはvalgrindのから出力されます。 「サイズ1の無効な書き込み」と「サイズ1の無効な読み取り」というエラーはどういう意味ですか?

    valgrind ./reverse Text ONe 
    ==3124== Memcheck, a memory error detector 
    ==3124== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
    ==3124== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
    ==3124== Command: ./reverse Text ONe 
    ==3124== 
    ==3124== Invalid write of size 1 
    ==3124== at 0x40060F: reverse (in /localServer/temp/C/reverse) 
    ==3124== by 0x400654: main (in /localServer/temp/C/reverse) 
    ==3124== Address 0x5203044 is 0 bytes after a block of size 4 alloc'd 
    ==3124== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
    ==3124== by 0x4005C6: reverse (in /localServer/temp/C/reverse) 
    ==3124== by 0x400654: main (in /localServer/temp/C/reverse) 
    ==3124== 
    ==3124== Invalid read of size 1 
    ==3124== at 0x4E88CC0: vfprintf (vfprintf.c:1632) 
    ==3124== by 0x4E8F898: printf (printf.c:33) 
    ==3124== by 0x400682: main (in /localServer/temp/C/reverse) 
    ==3124== Address 0x5203044 is 0 bytes after a block of size 4 alloc'd 
    ==3124== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
    ==3124== by 0x4005C6: reverse (in /localServer/temp/C/reverse) 
    ==3124== by 0x400654: main (in /localServer/temp/C/reverse) 
    ==3124== 
    1 Text txeT 
    2 ONe eNO 
    ==3124== 
    ==3124== HEAP SUMMARY: 
    ==3124==  in use at exit: 7 bytes in 2 blocks 
    ==3124== total heap usage: 3 allocs, 1 frees, 1,031 bytes allocated 
    ==3124== 
    ==3124== LEAK SUMMARY: 
    ==3124== definitely lost: 7 bytes in 2 blocks 
    ==3124== indirectly lost: 0 bytes in 0 blocks 
    ==3124==  possibly lost: 0 bytes in 0 blocks 
    ==3124== still reachable: 0 bytes in 0 blocks 
    ==3124==   suppressed: 0 bytes in 0 blocks 
    ==3124== Rerun with --leak-check=full to see details of leaked memory 
    ==3124== 
    ==3124== For counts of detected and suppressed errors, rerun with: -v 
    ==3124== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 0 from 0) 
    

    ありがとうございます。

    答えて

    3

    あなたは、逆順で返されたポインタの使い方の後、次のようにループの中に自由に置くべきです。

    int main (int argc, char** argv) { 
        char *reverseStrPtr; 
    
        if (argc > 1) { 
         for (int i = 1; i < argc; ++i) { 
          reverseStrPtr = reverse(argv[i]); 
          printf("%d\t%s\t%s\n", i, argv[i], reverseStrPtr); 
          free(reverseStrPtr); 
         } 
        } 
    
        return 0; 
    } 
    

    また、valgrindエラーは、下の行がreverseであることに基づいています。

    t[count] = '\0'; /* Add end of string */ 
    

    単にあなたがカウント多くのバイトを割り当てたときに、あなたのインデックス範囲は[0, count)で、置きます。したがって、カウントにアクセスしようとすると、(count+1)ビット目にアクセスすることと同等であり、これはアクセス違反です。

    修正する必要があるのは、割り当てたメモリ容量((count+1)バイト)です。終了バイトを配置するには余分なバイトが必要です'\0'文字。

    char* reverse(char* text) { 
        int count = strLen(text); 
        char* t = malloc(count+1); // +1 for the terminating '\0' 
    
        for (int i = count; i > 0; --i) { t[count - i] = text[i-1];} 
        t[count] = '\0'; /* Add end of string */ 
    
        return t; 
    } 
    
    +0

    クイックフードと女の子がそれをやる方法です。 upvoteをしてください。 – Bathsheba

    1

    reverse(argv[i])から返されたポインタと、freeから返されたポインタを保持する必要があります。

    一つの方法は、(彼らは難読化することができますように)すべての人の好みにはない深い表現内

    int main (int argc, char** argv) { 
        char* s; 
    
        // if (argc > 1) { Comment out the redundant check 
         for (int i = 1; i < argc; ++i) { 
          printf("%d\t%s\t%s\n", i, argv[i], s = reverse(argv[i])); 
          free(s); 
         } 
        //} 
        return 0; 
    } 
    

    割り当てにわずかmainを調整することであるが、彼らはこのような事例ではうまく動作します。私はあなたがCのようなものに慣れるべきilkです。

    また、t[count] = '\0';はあなたのバッファーをオーバーランさせます - その振る舞いは未定義です。あなたが必要ですmalloc(1 + count);

    +0

    Bathshebaありがとうございました。 –

    +0

    _quicheの食べる人とgirls_;のアップヴォート;) – LPs

    関連する問題