This question already has answers here:
Closed 10 months ago.
How dangerous is it to access an array out of bounds?
(10个答案)
我有一个字符数组,我想删除空白之前或之后,或两者,词(或短语),而不是在中间。
例如:
“你好”->“你好”
“你好”->“你好”
“你好”->“你好”
" " --> ""
这是我的代码:
#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字节。
接下来,在删除前导空白之前realloc,例如。
        t = realloc(t, sizeof(char)*n);
        for (int i = 0; i <= n - 1; ++i)

未指定由调用realloc截断的字节(如果有)。相反,您需要在调用t之前对realloc进行操作以删除前导空格(然后仍然不能保证会调整任何内存)
接下来,您可以多次调用realloc,此时您只需对s中的t的原始副本进行操作,以删除前导/尾随空白,然后在最后对realloc进行一次调用。malloc/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 - C:指针分配错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54391017/

10-16 07:10