在函数中用malloc替换字符串,并在另一个函数中使用它

在函数中用malloc替换字符串,并在另一个函数中使用它,c,string,memory,segmentation-fault,malloc,C,String,Memory,Segmentation Fault,Malloc,以下是我的两个功能: void base(char *str) { char *without_spaces; without_spaces = remove_spaces(str); printf("Without spaces length : %d \n", strlen(without_spaces)); // SEGFAULT HERE ! free(without_spaces);

以下是我的两个功能:

void base(char *str)
{
    char *without_spaces;
    without_spaces = remove_spaces(str);                                   
    printf("Without spaces length : %d \n", strlen(without_spaces)); // SEGFAULT HERE !
    free(without_spaces);
}

char *remove_spaces(char *source)
{
  char *result;
  int i = 0;
  result = malloc(strlen(source) + 1);
  while (*source != 0)
  {
     if (*source != ' ') {
      result[i] = *source;
      i++;
     }

     source++;
  }
  result[i] = '\0';
  // If I make the printf here it's work's
  return (result);
}
下面是我如何调用基函数(stdin提供的字符)


我认为这些函数在逻辑上有点混乱,读取的函数也会进行复制,我更喜欢一个aproch,其中有一个函数计算到malloc的有效长度,然后一个用于复制,最后一个用于从stdin读取

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

static size_t   ft_strlen(const char *str)
{
    size_t      len;

    len = 0;
    while (*str != '\0')
    {
        if (*str != ' ')
            len++;
        str++;
    }
    return (len);
}

char            *delete_spaces(const char *str)
{
    const size_t        size = ft_strlen(str);
    char                *nospaces;
    size_t              p;

    if (!(nospaces = malloc(size + 1)))
        return (NULL);
    p = 0;
    while (*str)
    {
        if (*str != ' ')
            nospaces[p++] = *str;
        str++;
    }
    nospaces[p] = '\0';
    return (nospaces);
}

int             main(int ac, char **av)
{
    char    *nospaces;

    if (ac < 2)
        return (0);
    nospaces = delete_spaces(av[1]);
    printf("nospaces: %s\n", nospaces);
    free(nospaces);
    return (0);
}
#包括
#包括
静态大小(常量字符*str)
{
尺寸透镜;
len=0;
而(*str!='\0')
{
如果(*str!='')
len++;
str++;
}
返回(len);
}
char*delete_空格(const char*str)
{
const size\u t size=ft\u strlen(str);
char*nospaces;
尺寸t p;
如果(!(nospaces=malloc(大小+1)))
返回(空);
p=0;
while(*str)
{
如果(*str!='')
nospaces[p++]=*str;
str++;
}
nospaces[p]='\0';
返回(nospaces);
}
内部主(内部ac,字符**av)
{
char*nospaces;
if(ac<2)
返回(0);
nospaces=delete_空格(av[1]);
printf(“nospaces:%s\n”,nospaces);
免费(无空间);
返回(0);
}
/a、 out“使用somes空格测试字符串” 给出:nospaces:testingastringwithsomesspaces

然后,在本例中,您还将对正确的大小进行malloc(源-空格数+1)

顺便说一下,如果您使用clang编译,您可以添加: -fsanitize=地址-g3

到编译标志 使用-Weverything-Werror
在试图找到此类bug时也是一个很好的实践

我认为这些函数在逻辑上有点混乱,读取的函数也会进行复制,我更喜欢一个aproch,其中有一个函数计算到malloc的有效长度,然后一个用于复制,最后一个用于从stdin读取

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

static size_t   ft_strlen(const char *str)
{
    size_t      len;

    len = 0;
    while (*str != '\0')
    {
        if (*str != ' ')
            len++;
        str++;
    }
    return (len);
}

char            *delete_spaces(const char *str)
{
    const size_t        size = ft_strlen(str);
    char                *nospaces;
    size_t              p;

    if (!(nospaces = malloc(size + 1)))
        return (NULL);
    p = 0;
    while (*str)
    {
        if (*str != ' ')
            nospaces[p++] = *str;
        str++;
    }
    nospaces[p] = '\0';
    return (nospaces);
}

int             main(int ac, char **av)
{
    char    *nospaces;

    if (ac < 2)
        return (0);
    nospaces = delete_spaces(av[1]);
    printf("nospaces: %s\n", nospaces);
    free(nospaces);
    return (0);
}
#包括
#包括
静态大小(常量字符*str)
{
尺寸透镜;
len=0;
而(*str!='\0')
{
如果(*str!='')
len++;
str++;
}
返回(len);
}
char*delete_空格(const char*str)
{
const size\u t size=ft\u strlen(str);
char*nospaces;
尺寸t p;
如果(!(nospaces=malloc(大小+1)))
返回(空);
p=0;
while(*str)
{
如果(*str!='')
nospaces[p++]=*str;
str++;
}
nospaces[p]='\0';
返回(nospaces);
}
内部主(内部ac,字符**av)
{
char*nospaces;
if(ac<2)
返回(0);
nospaces=delete_空格(av[1]);
printf(“nospaces:%s\n”,nospaces);
免费(无空间);
返回(0);
}
/a、 out“使用somes空格测试字符串” 给出:nospaces:testingastringwithsomesspaces

然后,在本例中,您还将对正确的大小进行malloc(源-空格数+1)

顺便说一下,如果您使用clang编译,您可以添加: -fsanitize=地址-g3

到编译标志 使用-Weverything-Werror
在尝试查找此类错误时也是一种很好的做法

调试器告诉了您什么?您确定
str
正确地以NULL结尾吗?在使用它之前是否检查了
malloc()
中的返回值?它可能会失败并返回NULL-但您的代码假定它是有效的。您的系统可能不允许您分配0.5 MiB的数据,尽管这是不寻常的。或者您有一些其他操作正在打乱堆,
malloc()
从堆中分配数据。
valgrind
输出没有显示seg错误,因此它与问题没有任何直接关系。有趣的
valgrind
输出将来自程序因分段错误而崩溃的运行。当我在包含357938字节数据的文件上运行您的代码时,您的程序将答案列为324220。也就是说,它正确地忽略了不适合分配空间的多余数据。我使用的文件实际上是一组随机的英文月份名称,每行一个,50000行。我在macOS Sierra 10.12.1上测试GCC 6.2.0。(遗憾的是,目前这台机器上没有工作的
valgrind
)调试器告诉您了什么?您确定
str
正确地以NULL结尾吗?在使用它之前,您是否检查了
malloc()
的返回值?它可能会失败并返回NULL-但您的代码假定它是有效的。您的系统可能不允许您分配0.5 MiB的数据,尽管这是不寻常的。或者您有一些其他操作正在打乱堆,
malloc()
从堆中分配数据。
valgrind
输出没有显示seg错误,因此它与问题没有任何直接关系。有趣的
valgrind
输出将来自程序因分段错误而崩溃的运行。当我在包含357938字节数据的文件上运行您的代码时,您的程序将答案列为324220。也就是说,它正确地忽略了不适合分配空间的多余数据。我使用的文件实际上是一组随机的英文月份名称,每行一个,50000行。我在macOS Sierra 10.12.1上测试GCC 6.2.0。(遗憾的是,目前这台机器上没有工作的
valgrind
。)我的报税表周围的()仅仅是因为我使用的编码规则。我报税表周围的()仅仅是因为我使用的编码规则
#include <stdlib.h>
#include <stdio.h>

static size_t   ft_strlen(const char *str)
{
    size_t      len;

    len = 0;
    while (*str != '\0')
    {
        if (*str != ' ')
            len++;
        str++;
    }
    return (len);
}

char            *delete_spaces(const char *str)
{
    const size_t        size = ft_strlen(str);
    char                *nospaces;
    size_t              p;

    if (!(nospaces = malloc(size + 1)))
        return (NULL);
    p = 0;
    while (*str)
    {
        if (*str != ' ')
            nospaces[p++] = *str;
        str++;
    }
    nospaces[p] = '\0';
    return (nospaces);
}

int             main(int ac, char **av)
{
    char    *nospaces;

    if (ac < 2)
        return (0);
    nospaces = delete_spaces(av[1]);
    printf("nospaces: %s\n", nospaces);
    free(nospaces);
    return (0);
}