C:指针分配错误

标签 c arrays visual-studio-2017 out-of-memory heap-corruption

<分区>

我有一个字符数组,我想删除单词(或短语)之前或之后的空格,而不是中间的空格。

例如:

“你好”-->“你好”

“你好”-->“你好”

“你好”-->“你好”

""--> ""

这是我的代码:

#include <stdlib.h>
#include <string.h>

int main(void) 
{
    char s[] = " prova ";
    char *t = NULL;
    if (s == NULL)
    {
        t = NULL;
    }
    else {
        int n = strlen(s);
        t = malloc(sizeof(char)* (n + 1));
        for (int i = 0; i <= n; ++i)
        {
            t[i] = s[i];
        }
        int k = 0;
        if (s[0] == ' ')
        {
            ++k;
            t = realloc(t, sizeof(char)*n);
            for (int i = 0; i <= n - 1; ++i)
            {
                t[i] = s[i + 1];
            }
        }

        if (s[n - 1] == ' ')
        {
            if (k == 1)
            {
                int j = 0;
                t = realloc(t, sizeof(char)*(n - 1));
                for (int i = 0; i <= n - 2; ++i)
                {
                    t[i] = t[i];
                    j = i;
                }
                t[j] = 0;
            }
            else
            {
                int j = 0;
                t = realloc(t, sizeof(char)*n);
                for (int i = 0; i <= n - 1; ++i)
                {
                    t[i] = t[i];
                    j = i;

                }
                t[j] = 0;
            }
        }
    }
    return t;
}

调试没有给我报错之类的,但是我知道内存和堆有问题,不知道怎么去掉。

我在这个平台上查找了其他与我类似的问题,它们都存在,但没有一个答案解决了我的问题。

请多多指教,谢谢

最佳答案

您的代码中存在大量小错误,开头为:

if (s == NULL)

s 永远不能为 NULL 除非您的编译器完全损坏或者您的堆栈少于 8 字节。

接下来,您在删除前导空格之前重新分配,例如

        t = realloc(t, sizeof(char)*n);
        for (int i = 0; i <= n - 1; ++i)

未指定调用 realloc 截断了哪些(如果有)字节。相反,您需要在 t 上操作以在调用 realloc 之前删除前导空格(然后您仍然不能保证任何内存都会被调整)

接下来,您多次调用realloc,此时您应该简单地对t 中的s 的原始副本进行操作,以删除前导/尾随空格,然后在最后调用 reallocmalloc/realloc 从效率的角度来看是相对昂贵的调用,不应重复调用。

重新整理一下逻辑,你可以这样做:

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

int main(void) 
{
    char s[] = " prova ";
    char *t = NULL;
    size_t n = strlen(s);           /* strlen returns size_t */
    int k = 0;

    t = malloc (n + 1);             /* sizeof(char) is 1 */
    if (t == NULL) {                /* validate ALL allocations */
        perror ("malloc-t");
        return 1;
    }

    for (size_t i = 0; i <= n; i++) /* copy s to t */
        t[i] = s[i];

    while (t[k] == ' ')             /* count leading whitespace */
        k++;

    for (size_t i = 0, j = k; j <= n; i++, j++) /* remove whitespace */
        t[i] = t[j];

    n -= k;                         /* update n */

    while (n && t[n - 1] == ' ')    /* remove trailing whitespace */
        t[n-- - 1] = 0;

    void *tmp = realloc (t, n + 1); /* realloc with tmp varaible */
    if (tmp == NULL) {              /* validate ALL allocations */
        perror ("realloc-t");
        return 1;
    }
    t = tmp;                        /* assign new block to t */

    printf ("t: '%s'\n", t);
    free (t);                       /* don't forget to free memory */

    return (int)n;
}

示例使用/输出

$ ./bin/str_trim_realloc
t: 'prova'

内存使用/错误检查

$ valgrind ./bin/str_trim_realloc
==26078== Memcheck, a memory error detector
==26078== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==26078== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==26078== Command: ./bin/str_trim_realloc
==26078==
t: 'prova'
==26078==
==26078== HEAP SUMMARY:
==26078==     in use at exit: 0 bytes in 0 blocks
==26078==   total heap usage: 2 allocs, 2 frees, 14 bytes allocated
==26078==
==26078== All heap blocks were freed -- no leaks are possible
==26078==
==26078== For counts of detected and suppressed errors, rerun with: -v
==26078== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

关于C:指针分配错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54391017/

相关文章:

c - 在 C 编程中的链表末尾追加一个元素

c - 使用 PIC 微处理器上的 C 语言进行二进制输出以实现 MIDI 输出

c - 重新诠释内存

java - 二维 boolean 数组垂直、水平和对角线赋值

c++ - 为 Visual Studio 2017 构建 boost 1.64

c - 将动态分配的结构数组的成员元素初始化为零

php - 使用 codeigniter 将 row_array 添加到 result_array foreach 循环?

java - 创建一个计算数组平均值的方法 (java)

typescript 提示 : Cannot find name 'Notification'

c++ - 在 VS2017 中搜索内存