1

次のコードがあり、作成中のプログラムで作業する「パス」の文字列を編集します。

私の問題は、コードが機能することですが、理由がわからないか、より明確にするために、 に追加strcatできる理由がわかりません。すべてが動的文字列を使用しているため、そうする必要はありません。しかし、私がそれをしようとすると、失敗しますsrcdestrealloc destrealloc

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

    int main(int argc, char** argv) {
        char *src = argv[1];
        char *dest = argv[2];
        char *d_basedir;
        int s_length = strlen(src);

        printf("dest starts as %s: length %zu\n", dest, strlen(dest));
        printf("src starts as %s: length %zd\n", src, strlen(src));

        if(!(src[s_length - 1] == '/')) {
            if((d_basedir = strrchr(src, '/')+1) != NULL) {
                printf("basedir is %s\n", d_basedir);
                strcat(dest, d_basedir);
                printf("dest changed to %s: length %zd\n", dest, strlen(dest));
            }
        }

        printf("dest ends as %s: length %zd\n", dest, strlen(dest));

        return 0;
    }
4

5 に答える 5

1

ホスト環境はargv[]配列を提供しますが、このメモリを割り当てていないため、再割り当てを試みるべきではありません。絶対に改造してはいけませんargv[]。変更を加えたい場合は、最初に (mallocなどを使用して) 文字列のコピーを作成します。少なくとも、十分なスペースがあるかどうか、またはrealloc連結する前に使用する必要があるかどうかを確実に知ることができます。

于 2013-01-29T23:15:15.583 に答える
0

運が良ければうまくいきます。それで全部です ;-)

dest に追加すると、プログラムが割り当てたメモリの一部が上書きされますが、重要なことには使用されません。だからこそ「働く」のです。

malloc によって割り当てられなかったメモリを再割り当てすることはできません。main() に渡される引数は、メモリのこれらの部分の 1 つです。

あなたが望むのは、新しいパスに十分な大きさの新しいメモリをmallocし、必要なものをstrcpyとstrcatにすることです。

于 2013-01-29T23:15:07.577 に答える
0
strcat(dest, d_basedir);

実際には次と同等です:

strcat(argv[2], d_basedir);

これは未定義の動作です。今日はうまくいき、明日は失敗するかもしれません。argv[2][0]まで書き込む権利がありますが、argv[2][strlen(argv[2])]その要素を超えて書き込むこと (strcat呼び出しで行っていること) は未定義の動作です。

于 2013-01-29T23:14:01.807 に答える
0

strcat気にしませんdest。これは単なる char へのポインタであり、strcatには十分です。

は環境からなのでargv[2]、dest (argv[2]) への追加は許可されていません。正しい方法は、十分なメモリを割り当て、それにコピーargv[2]して追加d_basedirすることです

char *dest = malloc(strlen(argv[2]) + strlen(d_basedir) + 1);
strcpy(dest, argv[2]);
strcat(dest, d_basedir);
于 2013-01-29T23:16:47.977 に答える
0

個人的には、この種のコードには realloc/malloc を使用しません。

PATH_MAX (場合によっては MAX_PATH) を使用して、必要な最長パスを決定できます。

 char dest[PATH_MAX]; 

 strcpy(dest, d_basedir);
 strcat(dest, argv[2]); 

(これは、src-path の d_basedir を dest の最後に追加する、あなたが書いたものとは少し異なりますが、これは私には間違っているように見えます)

于 2013-01-30T00:08:18.837 に答える