[英]C: How do I pass malloc'ed pointers into a function and free them?
我正在使用套接字和線程來開發客戶端服務器程序。 我有一個用於客戶端的菜單,並且正在嘗試從客戶端向服務器發送一個字符,然后調用相應的功能。 我正在嘗試使用指針和malloc,但我認為我不太了解如何傳遞它們並釋放它們。 我遇到內存泄漏和類似錯誤:
./server':兩次釋放或損壞(fasttop):0x00007f37dc000a50 ***
和
分段故障
這是我的客戶菜單:
char *choice = (char*) malloc(sizeof(char));
do {
// get a string from the server
get_msg(sockfd);
printf("\nFile and Information System\n");
printf("===========================\n");
printf("1. Show IP and Student ID\n");
printf("2. Display server time\n");
printf("3. Display system information\n");
printf("4. List files on server\n");
printf("5. File Transfer\n");
printf("6. Exit\n");
printf("Enter choice: ");
scanf("%s", choice);
//Send input to server
send_menu_choice(sockfd, choice);
switch (*choice)
{
case '1':
get_ip(sockfd);
break;
case '2':
get_time(sockfd);
break;
case '3':
get_and_send_uname(sockfd);
break;
case '4':
get_file_list(sockfd);
break;
case '5':
printf("File transfer not yet implemented\n");;
break;
case '6':
printf("Exiting...\n");
break;
default:
printf("Invalid choice\n");
}
//if(menu_choice != NULL)
//{
// free(menu_choice);
//}
} while (*choice != '6');
if (choice != NULL)
{
free(choice);
}
將菜單選項發送到服務器:
void send_menu_choice(int socketNumber, char *choice)
{
printf("Sending menu choice...\n");
size_t n = strlen(choice) + 1;
writen(socketNumber, (unsigned char *) &n, sizeof(size_t));
writen(socketNumber, (unsigned char *) choice, n);
printf("Sent choice: %s\n\n", choice);
}
服務器端:
char *menu_choice = (char*) malloc(sizeof(char));
do {
printf("Waiting for client to select option...\n\n");
send_msg(connfd);
get_menu_choice(connfd, menu_choice);
printf("Client %d choice was: %s\n", connfd, menu_choice);
switch (*menu_choice)
{
case '1':
send_ip(connfd);
break;
case '2':
send_time(connfd);
break;
case '3':
get_and_send_uname(connfd, *uts);
break;
case '4':
send_file_list(connfd);
break;
case '5':
printf("File Transfer not implemented\n");
break;
case '6':
break;
default:
printf("Invalid choice\n");
}
//if(menu_choice != NULL)
//{
// free(menu_choice);
//}
} while (*menu_choice != '6');
if (choice != NULL)
{
free(choice);
}
從客戶端獲取菜單選項:
void get_menu_choice(int socketNumber, char *choice)
{
size_t n;
readn(socketNumber, (unsigned char *) &n, sizeof(size_t));
readn(socketNumber, (unsigned char *) choice, n);
printf("Received: %zu bytes\n\n", n);
}
發送消息(服務器端):
void send_msg(int socket) { char msg_string[] = "\\nPlease enter an option:"; size_t n = strlen(msg_string) + 1; writen(socket, (unsigned char *) &n, sizeof(size_t)); writen(socket, (unsigned char *) msg_string, n); }
獲取信息(客戶端:
void get_msg(int socket) { char msg_string[32]; size_t k; readn(socket, (unsigned char *) &k, sizeof(size_t)); readn(socket, (unsigned char *) msg_string, k); printf("%s\\n", msg_string); }
我在這里做錯了什么? 我不會影響指針指向的位置的值嗎?
在do
循環中,您反復釋放指針
if(menu_choice != NULL)
{
free(menu_choice);
}
但是,您只能在循環之前分配一次。
請允許我將循環壓縮到以下關鍵行:
char *choice = (char*) malloc(sizeof(char));
do {
scanf("%s", choice);
switch (*choice) {
case '6':
printf("Exiting...\n");
break;
default:
printf("Invalid choice\n");
}
if (choice != NULL)
{
free(choice);
}
} while (*choice != '6');
此循環存在嚴重缺陷。 您不僅會使用1個字節的內存來存儲2( scanf
應該使用%c
而不是%s
),而且如果您選擇非6的值,則循環不僅會訪問釋放的內存,而且還會導致雙重釋放(您的錯誤)。 另一方面,如果選擇6,則在釋放內存后正在訪問內存,這也是一個非常嚴重的錯誤。
循環終止后,您應該釋放內存。
服務器端,
char *menu_choice = (char*) malloc(sizeof(char));
您分配一個字符。
然后在get_menu_choice()稱為get_menu_choice(connfd, menu_choice)
使用1個字節分配menu_choice
,
void get_menu_choice(int socketNumber, char *choice)
{
size_t n;
readn(socketNumber, (unsigned char *) &n, sizeof(size_t));
readn(socketNumber, (unsigned char *) choice, n);
您將n
個字節存儲到choice
...
這似乎不正確。
一字節分配足夠了嗎? 意思是, n
取值> 1?
這是一個通用答案,這是我在項目中使用的功能:
/* this is safe free() and no not what you asked, check next one */
void my_free(void *ptr)
{
if (ptr) {
free(ptr);
}
}
/* this is almost same as safe free above but also sets the pointer to NULL */
void my_freep(void **ptr)
{
if (*ptr != NULL) {
free(*ptr);
}
*ptr = NULL;
}
然后像這樣調用my_freep
my_freep((void**)&buffer);
注意這里的buffer
被定義為指針(即char *buffer;
)。
希望能有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.