下面是一個使用strdup()
簡化的內存分配的每個新行版本文本。它還使用'x'版本的內存分配函數來簡化內存不足錯誤處理(即使非標準也是一種常見的習慣用法)。
因此,真正保留的所有複雜性(最終不會太多)是管理字符串指針數組的增長。我認爲這樣可以更輕鬆地將處理每個字符串與處理指針數組分開。原來的代碼讓這兩個領域感到困惑。
// these variants allocate memory, but abort program on failure
// for simplified error handling - you may need different
// error handling, but often this is enough
//
// Also, your platform may or may not already have these functions
// simplified versions are in the example.
void* xmalloc(size_t size);
void* xrealloc(void* ptr, size_t size);
char* xstrdup(char const* s);
char** receiveCode(int socket){
size_t lines = 0;
char** code = xmalloc((lines + 1) * sizeof(*code));
*code = NULL;
while(1){
package_struct *aPackage = receivePackage(socket);
if(aPackage->type=='F') {
free(aPackage); // not 100% sure if this should happen here or not.
// Is a `package_struct` with type 'F' dynamically
// allocated or is a pointer to a static sentinel
// returned in this case?
break;
}
// why use `aPackage->size` when you use `strcpy()` to
// copy the string anyway? Just let `strdup()` handle the details
//
// If the string in the `pckage_struct` isn't really null terminated,
// then use `xstrndup(aPackage->package, aPackage->size);` or something
// similar.
char* line = xstrdup(aPackage->package);
++lines;
// add another pointer to the `code` array
code = xrealloc(code, (lines + 1) * sizeof(*code));
code[lines-1] = line;
code[lines] = NULL;
free(aPackage);
}
return code;
}
void* xmalloc(size_t size)
{
void* tmp = malloc(size);
if (!tmp) {
fprintf(stderr, "%s\n", "failed to allocate memory.\n";
exit(EXIT_FAILURE);
}
return tmp;
}
void* xrealloc(void *ptr, size_t size)
{
void* tmp = realloc(ptr, size);
if (!tmp) {
fprintf(stderr, "%s\n", "failed to allocate memory.\n";
exit(EXIT_FAILURE);
}
return tmp;
}
char* xstrdup(char const* s)
{
char* tmp = strdup(s);
if (!tmp) {
fprintf(stderr, "%s\n", "failed to allocate memory.\n";
exit(EXIT_FAILURE);
}
return tmp;
}
另外,我覺得如果aPackage->package
是一個字符串指針應澄清,或者如果它是char[]
的實際位置保持字符串數據(即,應該&aPackage->package
傳遞給strcpy()
/xstrdup()
?)。如果它真的是一個指針,它應該在aPackage
之前被釋放嗎?
下面有很多正確的答案:側欄,打破'ptr = realloc(ptr,size)'的習慣,除非你真的不在乎重新分配失敗是否會泄露你先前分配的內存。分配給temp並僅在成功時覆蓋prev指針。 – WhozCraig