为什么malloc无法使用strcpy?

时间:2017-06-19 15:36:11

标签: c string function malloc strcpy

char * removeChar(char * str, char c){
    int len = strlen(str);
    int i = 0;
    int j = 0;
    char * copy = malloc(sizeof(char) * (len + 1));
    while(i < len){
        if(str[i] != c){
            copy[j] = str[i];
            j++;
            i++;
        }else{
            i++;
        }
   }

    if(strcmp(copy, str) != 0){
        strcpy(str,copy);

    }else{
        printf("Error");
    }
    return copy;
}




int main(int argc, char * argv[]){
    char str[] = "Input string";
    char * input;
    input = removeChar(str,'g');
    printf("%s\n", input);
    free(input);
    return 0;
}

我不知道为什么每次我尝试运行它时,它总是说未初始化的变量并且在strcpy行和printf行中粘贴。

基本上这个函数是取一个字符串和一个字符并从字符串中删除那个字符(因为我正在学习malloc,这就是我写这个函数的原因)。

4 个答案:

答案 0 :(得分:4)

在while循环后执行:

copy[j] = '\0';

NULL - 终止你的字符串;这样它就可以使用来自<string.h>的方法,它假定字符串是以空的方式终止的。

PS:您应该看到的一个警告是在任何情况下都不会在函数中返回copy,因为现在如果if语句的条件错误,您的函数将不会返回有效的函数,所以添加这个:

return copy;

在您的功能结束时(现在已通过编辑进行了更正)。

除此之外,你应该仍然得到的唯一警告是main()未使用的参数,没有别的:

prog.c: In function 'main':
prog.c:32:14: warning: unused parameter 'argc' [-Wunused-parameter]
 int main(int argc, char * argv[]){
              ^~~~
prog.c:32:27: warning: unused parameter 'argv' [-Wunused-parameter]
 int main(int argc, char * argv[]){
                           ^~~~

答案 1 :(得分:3)

当您将字节从public ActionResult MyAction(CustomType FormData) { string SelectedValue = FormData.tab; // do something } 复制到str时,您不会在结尾处添加终止空字节。结果,copy将复制的字符读取到单元化的内存中,可能超过分配的内存块的末尾。这会调用undefined behavior

strcmp循环后,将终止空字节添加到while

此外,如果最后的copy块为false,则永远不会返回值。你需要为此返回一些东西,可能是复制的字符串。

if

答案 2 :(得分:2)

你从未初始化输入,有些编译器没有注意到, 该值从未在行

之前使用
input = removeChar(str, 'g');
你的代码中的

。所以他们发出诊断就是为了确定。

strcpy(str, copy)

卡在你的代码中,因为副本永远不会得到关闭的0字节和 所以取决于你的记忆的不确定性内容 分配内存后备副本的时刻,strcpy有多长 将运行,如果你最终得到一个SIGSEGV(或类似)。

strcpy将循环,直到它在您的内存中找到0字节。

答案 3 :(得分:0)

对于从字符串中删除字符的初学者,不需要动态创建字符数组,然后将此数组复制到原始字符串中。

您应该编写一个确实从字符串中删除指定字符的函数,或者根据排除指定字符的源字符串创建新字符串的函数。

这只是一个糟糕的设计,只会让用户感到困惑。这就是函数太复杂,并使用冗余函数,如mallocstrlenstrcmpstrcpy。事实上,它的副作用并不明显。此外,对于字符串的长度而不是int类型,使用了错误的类型size_t

至于你的功能实现,你忘了追加终止零&#39; \ 0&#39;到动态分配的数组中构建的字符串。

如果你确实想要从字符串中删除一个字符,那么该函数可以看起来像在演示程序中显示的那样。

#include <stdio.h>

char * remove_char(char *s, char c)
{
    char *p = s;

    while (*p && *p != c) ++p;

    for ( char *q = p; *p++; )
    {
        if (*p != c) *q++ = *p;
    }

    return s;
}

int main( void )
{
    char str[] = "Input string";

    puts(str);
    puts(remove_char(str, 'g'));

    return 0;
}

程序输出

Input string
Input strin

如果您正在学习函数malloc并想要使用它,那么在任何情况下都应该尝试实现正确的设计。

要使用malloc,您可以编写一个函数,根据排除指定字符的源字符串创建新字符串。例如

#include <stdio.h>
#include <stdlib.h>

char * remove_copy_char(const char *s, char c)
{
    size_t n = 0;

    for (const char *p = s; *p; ++p)
    {
        if (*p != c) ++n;
    }

    char *result = malloc(n + 1);

    if (result)
    {
        char *q = result;

        for (; *s; ++s)
        {
            if (*s != c) *q++ = *s;
        }

        *q = '\0';
    }

    return result;
}

int main( void )
{
    char *str = "Input string";

    puts(str);

    char *p = remove_copy_char(str, 'g');

    if ( p ) puts(p );

    free(p);

    return 0;
}

程序输出与上面相同。

Input string
Input strin

注意功能声明

char * remove_copy_char(const char *s, char c);
                        ^^^^^^

在这种情况下,源字符串可以是字符串文字。

char *str = "Input string";