c - 未初始化和内存错误(字符串和指针)
问题描述
这是我需要做的:删除给定字符串中出现频率最高的数字的所有出现
这是我所做的:写了两个函数;第二个将字符串中的所有整数提取到一个数组中,找到最常重复的整数,调用第一个函数在字符串中查找该数字,删除给定字符串中所有出现的数字
问题是当我编译它时它工作正常,但没有通过一系列自动生成的测试,并在我用 <------ 标记的行中显示“访问未初始化的值”和“内存错误”。
我知道这不完全是“最小可重现代码”,但我希望有人能指出问题所在,因为我在使用指针时遇到了很多类似的错误。
char* find_number(char* string,int search)
{
int sign=1;
int number=0,temp=0;
char* p = string;
while(*string != '\0') {<----------
p=string;
if(*string=='-') sign=-1;
else if(*string==' ') {
string++;
continue;
} else if(*string>='0' && *string<='9') {
temp=0;
while(*string != '\0' && *string>='0' && *string<='9') {
temp=temp*10+*string-'0';
string++;
}
number=temp*sign;
if(number==search) {
return p;
}
} else {
sign=1,number=0;
}
string++;
}
return NULL;
}
char* delete_most_frequent(char* string)
{
//writing all integers in a string to an array
char* pointer=string;
char* s = string;
int temp=0, sign = 1,i=0,array[1000],number=0,counters[1001]= {0},n=0;
while (*s != '\0') {<------------
if (*s == '-') sign = -1;<----------
else if (*s >= '0' && *s <='9') {<----------
temp = 0;
while (*s != '\0' && *s >= '0' && *s <= '9') {
temp = temp * 10 + *s - '0';
s++;
}
number=sign*temp;
if(number>=0 && number<=1000) {
array[i]=number;
i++;
}
}
number=0;
sign=1;
s++;
}
n=i;//size of the array
//finding the number that occurs most frequently
int max=0;
for (i=0; i<n; i++) {
counters[array[i]]++;
if(counters[array[i]]>counters[max]) {
max=array[i];
}
}
char* p=find_number(string,max);//pointer to the first digit of wanted number
//deleting the integer
while (*string != '\0') {
if (p != NULL) {
char *beginning = p, *end = p;
while(*end>='0' && *end<='9')
end++;
//while (*beginning++ = *end++);
while(*end != '\0'){
*beginning = *end;
beginning++;
end++;
}
*beginning = '\0';
} else string++;
p=find_number(string,max);
}
return pointer;//pointer to the first character of a string
}
int main()
{
char s[] = "abc 14 0, 389aaa 14! 15 1, 153";
printf("'%s'", delete_most_frequent(s));
return 0;
}
解决方案
将您的代码切割成可能导致问题的原因,您的模式看起来像
while(*string != '\0') {
:
while(*string != '\0' ...) {
:
string++;
}
:
string++;
}
所以你有两个嵌套的while循环,这两个循环都在推进指针,寻找一个NUL终止符来结束循环。问题是,如果内循环一直到达 NUL(它可能会更早停止,但可能不会),那么外循环中的增量将使指针增加超过NUL。然后它会愉快地通过(可能是无效的)内存寻找另一个可能不存在的 NUL。这是一个难以捕捉的问题,因为在您编写的大多数测试用例中,字符串后面可能有多个 NUL(很快),所以它看起来工作正常——您几乎必须专门编写一个测试用例来触发这种故障模式抓住这个。
一种解决方法是在递增之前检查您是否尚未处于 null 状态——if (*string) string++;
而不仅仅是string++;
推荐阅读
- amazon-web-services - 具有管理员权限的 IAM 用户能够使用未在其密钥策略中将此用户添加为密钥用户的密钥加密 EBS 卷
- mysql - 使用 GROUP BY 获取最新记录的记录
- mysql - 按 mysql 或 dax 类别汇总配对值
- azure - 本地开发时的 Azure Functions 成本
- swift - 缓存的 Xcode 派生数据未在 CI 中使用
- html - 如何在行中将标签向左浮动并向右跨越?
- javascript - 向传单地图上的圆圈添加度数标记
- c# - 将单个对象分配给对象列表
- google-cloud-automl - 如何可视化 Google Cloud 中 AutoML Table 为我创建的模型?
- c# - 无法跟踪,因为另一个具有相同键值的实例