[英]Char pointer in array is not freeing
我有一個char指針數組。 該數組有字符串。 當我想釋放分配給其中一個字符串的內存時,它可以工作,但是刪除后的字符串變成了垃圾。 這是我的代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 3
void AddName(char *Names[],int *size)
{
char str[100];
int len;
if (*size < MAX)
{
printf("Enter a string: ");
scanf(" %s", str);
len = strlen(str);
Names[*size] = (char *)malloc((len+1)*sizeof(char));
strcpy(Names[*size],str);
*size = *size+1;
}
else printf("Full Memory!!\n");
}
void RemoveName(char *Names[],int *size)
{
int loc;
if (*size > 0)
{
printf("Starting from 0. Enter the name's location: ");
scanf(" %d", &loc);
free(Names[loc]);
*size = *size-1;
}else printf("ERROR\n");
}
void PrintNames(char *Names[],int size)
{
int i;
for (i = 0; i<size; i++)
{
printf(" %s\t", Names[i]);
}
printf("\n");
}
main()
{
char *Names[MAX];
int size = 0;
int c;
do
{
printf("=========================\n");
printf("1- Add a new name.\n");
printf("2- Delete an old name.\n");
printf("3- Print names.\n");
printf("4- Exit.\n");
printf("=========================\n");
printf("Enter your choice: ");
scanf("%i", &c);
printf("=========================\n");
switch(c)
{
case 1: AddName(Names,&size);
break;
case 2: RemoveName(Names,&size);
break;
case 3: PrintNames(Names,size);
break;
case 4: printf("Good bye.\n");
break;
default: printf("ERROR: Bad input.\n");
}
}while(c != 4);
}
如果我在數組中打印名稱,它將顯示Carl Hello
。 如果在釋放Carl后嘗試再次打印,它會顯示↨Y
(它應打印Hello)。
您輸入的是Carl和Hello
名稱[0] =卡爾
名稱[1] =你好
現在,您釋放了Names [0]的內存。
當您打印名稱時,您嘗試打印已經釋放的Names [0],因此您將得到垃圾。
您需要移動所有指針以填充空白空間
在這種情況下,刪除Names [0]時,您只有一個條目,因此讓Names [0]指向Names [1]上的內存
當您刪除i處的條目時,您需要調整以下指針,直到列表末尾。
Names[i] -> Names[i+1]
除了RADAR在回答中發現的主要問題外,還有其他一些問題:
這里:
Names[*size] = (char *)malloc((len+1)*sizeof(char));
不要轉換malloc()
的返回值,並且sizeof(char)
始終為1,因此應為:
Names[*size] = malloc(len + 1);
您應該檢查malloc()
返回NULL
,因為它可能失敗並返回NULL
。
在這里,以及其他地方:
printf("Enter a string: "); scanf(" %s", str);
您可能會遇到問題,因為您要發送給printf()
的東西沒有以換行符結尾。 交互式輸入和輸出默認情況下在C中是行緩沖的,在某些系統上,直到輸入后 ,您才會看到該提示。 為避免這種情況,如果要確保立即顯示不以換行符結尾的某些輸出,請調用fflush(stdout)
。
main()
返回一個int
,如果您不想使用命令行參數,則正確的聲明為int main(void)
。 雖然main()
是一個函數返回一個值,你不必明確地返回一個,它是更好的形式,如果你做的。
這個:
scanf(" %s", str);
如果用戶輸入的字符數超過100個,則將導致Bad Times。 您可以使用scanf()
解決此問題,但使用fgets()
更好。
通常,使用scanf()
這種輸入策略很脆弱,特別是如果用戶輸入錯誤的內容時。 特別是如果您獲得大量輸入,則可以通過定義一些便捷函數來使用fgets()
獲取行和整數,然后重新使用這些函數,從而對自己有所幫助。
您的格式在某些地方非常糟糕。
這是考慮到以上所有因素的修改版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 3
#define BUFFER_LEN 100
/* Convenience function to get a line from
* standard input - caller must free */
char * get_line(void)
{
char str[BUFFER_LEN];
char * newstr;
int len;
/* Get line of input */
if ( !fgets(str, sizeof str, stdin) ) {
fprintf(stderr, "ERROR: Couldn't get string!\n");
exit(EXIT_FAILURE);
}
/* Remove trailing newline, if present */
len = strlen(str);
if ( len > 0 && str[len - 1] == '\n' ) {
str[--len] = 0;
}
/* Allocate memory and copy string */
if ( !(newstr = malloc(len + 1)) ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
strcpy(newstr, str);
return newstr;
}
/* Convenience function to get an integer from standard input */
long get_long(void)
{
char * str, *endptr;
long n;
str = get_line();
n = strtol(str, &endptr, 0);
if ( *endptr ) {
fprintf(stderr, "ERROR: You didn't enter an integer!\n");
exit(EXIT_FAILURE);
}
free(str);
return n;
}
/* Adds a name to a list */
void AddName(char * Names[], int * size)
{
if ( *size < MAX ) {
printf("Enter a string: ");
fflush(stdout);
Names[*size] = get_line();
*size += 1;
}
else {
printf("ERROR: List full!\n");
}
}
/* Removes a name from the list */
void RemoveName(char * Names[], int * size)
{
if ( *size > 0 ) {
int i;
long loc;
printf("Starting from 0, enter the name's location: ");
fflush(stdout);
/* Free the desired name... */
loc = get_long();
free(Names[loc]);
/* ...and move any names ahead of it back. */
for ( i = loc + 1; i < *size; ++i ) {
Names[i - 1] = Names[i];
}
*size -= 1;
}
else {
printf("ERROR: list empty!.\n");
}
}
/* Prints the names in the list */
void PrintNames(char * Names[], int size)
{
int i;
for ( i = 0; i < size; ++i ) {
printf(" %s\t", Names[i]);
}
putchar('\n');
}
/* Main function */
int main(void)
{
char * Names[MAX];
int size = 0;
long c;
do {
printf("=========================\n");
printf("1- Add a new name.\n");
printf("2- Delete an old name.\n");
printf("3- Print names.\n");
printf("4- Exit.\n");
printf("=========================\n");
printf("Enter your choice: ");
fflush(stdout);
c = get_long();
printf("=========================\n");
switch( c ) {
case 1:
AddName(Names, &size);
break;
case 2:
RemoveName(Names, &size);
break;
case 3:
PrintNames(Names, size);
break;
case 4:
printf("Good bye.\n");
break;
default:
printf("ERROR: Bad input.\n");
break;
}
} while ( c != 4 );
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.