Char* 函数从非 null 值返回 null

问题描述 投票:0回答:1

所以问题出在我的割包字符串函数上。它应该接受一个字符串、一个字符和一个整数数组,返回不带字符的字符串,并标记它删除的所有字符。

char* circumcisedString(char* og, char rem, int* checked)
{
    char circS[100];
    char* t= circS;
    char* og2 = og;
    while(*og2)
    {
        if(*og2 != rem)
        {
            *t = *og2;
            t++;
        }
        else
        {
            checked[og2 - og] = 1;
        }
        og2++;
    }
    *t = '\0';
    printf("%d ", circS);
    return circS;
}

void Three()
{
    char str[100]; scanf("%99s", str);
    char rem[100]; scanf("%99s", rem);
    int strl = strlen(str);
    int reml = strlen(rem);
    int checked[reml];
    for(int i = 0; i < reml; i++) checked[i] = 0;
    for(int i = 0; i < reml; i++)
    {

        if(!checked[i])
        {
            char* remstr = circumcisedString(rem, rem[i], checked);
            printf("%d ", remstr);
            int j = 0, c = 0;
            //j = mystrstr(str, remstr) - str;
            //while(j = strstr(str + j, remstr) + 1) c++;
        }
    }
}

打印 circS 的“%s”(这是我指向新字符串的指针)后,我得到了我想要的,直到我返回它。返回时,它只返回一个空地址。在仍在代码中的 printf 测试中,“print("%d", circS)" 输出 6421472 作为它的内存位置,而 printf("%d ", remstr) 输出 0。有谁知道可能是什么问题是什么?

c string pointers
1个回答
0
投票

本质上,

circS
指向的数组在函数结束后超出了范围,因此函数的堆栈帧被清除,并且不存在的数组的地址不再存在。 当你打电话时

printf("%d ", circS);

数组仍在作用域内,堆栈帧仍然存在,因此

circS
指向的地址仍然有效。让我们假设
circS = 0x0061FBE0
。当
circS
返回时,将
0x0061FBE0
放入
remstr
。但是,由于
circS
指向的数组超出了范围并且堆栈帧被释放,因此
0x0061FBE0
不再指向该数组,而是指向我们不应该搞乱的其他内容,这使其现在成为空地址。


如何修复?

删除某个字符的重复项后,可以直接修改原始字符串参数并返回该参数(或者什么也不返回,使其成为一个

void
函数)。 如果您需要保存原始字符串,只需使用
memcpy
进行复制即可。

char* circumcisedString(char* og, char rem, int* checked)
{
    // do something with og
    
    return og;
    // or return nothing
}

这段代码之所以有效,是因为传入函数的参数是从调用函数的位置开始的,而函数结束后,参数仍然会存在于调用函数的地方,所以当函数返回到在调用它的地方,内存将保持有效。 (在您的具体情况下,

og
将是一个有效的内存地址,即
rem
)。


关于您的代码的其他注释:

使用可变变量提供的大小声明变量是不安全的。

int checked[reml];

这很糟糕,因为编译器应该知道为数组分配的内存量,但变量的大小有时只能在运行时知道。将数组大小设置为不会被超越的上限。

另外,要默认初始化一个数组,你可以这样做

int arr[8] = {0};

而不是循环遍历数组;它只是更干净

© www.soinside.com 2019 - 2024. All rights reserved.