[英]Weird behaviour of C strcpy
我在C中編寫了一個小程序。它編譯得很完美並且工作,當我通過我的Makefile
和clang
編譯它時,然而,在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.