簡體   English   中英

C strcpy的奇怪行為

[英]Weird behaviour of C strcpy

我在C中編寫了一個小程序。它編譯得很完美並且工作,當我通過我的Makefileclang編譯它時,然而,在Xcode中,這個函數表現得不像它應該的那樣(或者它表現得像它應該和clang忽略它)。

size_t getUrlForArgAndPlatform(char **dest, const char *arg, const char *platform) {
    int isLinux = strcmp(platform, "Linux");
    int isOSX = strcmp(platform, "Darwin");

    char *platformUrlDelimiter = malloc(6 + 1);
    if (isLinux == 0) {
        strcpy(platformUrlDelimiter, "linux");
    } else if (isOSX == 0) {
        strcpy(platformUrlDelimiter, "osx");
    } else {
        strcpy(platformUrlDelimiter, "common");
    }

    int length = (int) strlen(kBaseUrl);
    length += strlen(platformUrlDelimiter);
    length += strlen(arg);
    length += 5;

    char *buffer = (char *) malloc(length);
    if (buffer == NULL) {
        exit(EXIT_FAILURE);
    }
    strcpy(buffer, kBaseUrl);
    strcat(buffer, "/");
    strcat(buffer, platformUrlDelimiter);
    strcat(buffer, "/");
    strcat(buffer, arg);
    strcat(buffer, ".md");

    *dest = malloc(strlen(buffer) + 1);
    strcpy(*dest, buffer);

    free(platformUrlDelimiter);
    free(buffer);

    return strlen(buffer) + 1;
}

它在10次中工作了4次。在另外6次中,Xcode告訴我它在使用SIGBRT strcpy(*dest, buffer) SIGBRT 如果我看一下調試器,我看到buffer包含兩次相同的字符串。 為什么?

您為buffer計算的大小不太正確:

int length = (int) strlen(kBaseUrl);
length += strlen(platformUrlDelimiter);
length += strlen(arg);
length += 5;

最后一部分應為'+6',因為你需要2次"/"空間, ".md" 空格終止NUL

(已經提到了不正確的長度。)

你的代碼中有很多無意義的復制。 由於您不修改platformUrlDelimiter ,因此無需復制它兩次。 這更簡單:

const char *platformUrlDelimiter = "common";
if (isLinux == 0) {
    platformUrlDelimiter = "linux";
} else if (isOSX == 0) {
    platformUrlDelimiter = "osx";
}

並刪除對free (platformUrlDelimiter)的調用。

每次調用strcat() (可能)都必須不必要地遍歷緩沖區。 我會寫:

int length = strlen(kBaseUrl)
           + strlen(platformUrlDelimiter)
           + strlen(arg)
           + 6;

*dest = malloc(length);
if (*dest) {
  sprintf (*dest, "%s/%s/%s.md", kBaseUrl, platformUrlDelimiter, arg);
} else {
  /* Error */
}

return length;

現在根本不需要使用buffer

此外,代碼末尾還有一個真正的錯誤

free(buffer);

return strlen(buffer) + 1;

釋放后,您不得以任何方式使用buffer的值。

暫無
暫無

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

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