[英]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.