首页 > 解决方案 > 未初始化和内存错误(字符串和指针)

问题描述

这是我需要做的:删除给定字符串中出现频率最高的数字的所有出现

这是我所做的:写了两个函数;第二个将字符串中的所有整数提取到一个数组中,找到最常重复的整数,调用第一个函数在字符串中查找该数字,删除给定字符串中所有出现的数字

问题是当我编译它时它工作正常,但没有通过一系列自动生成的测试,并在我用 <------ 标记的行中显示“访问未初始化的值”和“内存错误”。

我知道这不完全是“最小可重现代码”,但我希望有人能指出问题所在,因为我在使用指针时遇到了很多类似的错误。

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;
}

标签: cstringpointersmemory

解决方案


将您的代码切割成可能导致问题的原因,您的模式看起来像

    while(*string != '\0') {
            :
        while(*string != '\0' ...) {
                :
            string++;
        }
            :
        string++;
    }

所以你有两个嵌套的while循环,这两个循环都在推进指针,寻找一个NUL终止符来结束循环。问题是,如果内循环一直到达 NUL(它可能会更早停止,但可能不会),那么外循环中的增量将使指针增加超过NUL。然后它会愉快地通过(可能是无效的)内存寻找另一个可能不存在的 NUL。这是一个难以捕捉的问题,因为在您编写的大多数测试用例中,字符串后面可能有多个 NUL(很快),所以它看起来工作正常——您几乎必须专门编写一个测试用例来触发这种故障模式抓住这个。

一种解决方法是在递增之前检查您是否尚未处于 null 状态——if (*string) string++;而不仅仅是string++;


推荐阅读