C - 内存泄漏,函数 return Char*

C - Memory Leak, function return Char*

复习 C 编程,我遇到了释放内存的问题。下面的程序给了我下面的编译器警告,我很难解决。 Valgrind 还通知存在内存泄漏,但我在使用 malloc() 分配的内存上使用 free。任何关于我在 main() 中尝试释放指针 'alpha' 上的内存时做错了什么的指导表示赞赏?

编译器警告

In function ‘main’:/alphabetArrayPractice/src/main.c:37:10: warning: passing argument 1 of ‘free’ makes pointer from integer without a cast [-Wint-conversion]
   37 |     free(*alpha);
      |          ^~~~~~
      |          |
      |          char
In file included from /alphabetArrayPractice/src/main.c:2:
/usr/include/stdlib.h:565:25: note: expected ‘void *’ but argument is of type ‘char’
  565 | extern void free (void *__ptr) __THROW;

Valgrind 报告

==950908== 
==950908== HEAP SUMMARY:
==950908==     in use at exit: 27 bytes in 1 blocks
==950908==   total heap usage: 2 allocs, 1 frees, 1,051 bytes allocated
==950908== 
==950908== 27 bytes in 1 blocks are definitely lost in loss record 1 of 1
==950908==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==950908==    by 0x10919E: get_alphabet_array (main.c:5)
==950908==    by 0x109230: main (main.c:23)
==950908== 
==950908== LEAK SUMMARY:
==950908==    definitely lost: 27 bytes in 1 blocks
==950908==    indirectly lost: 0 bytes in 0 blocks
==950908==      possibly lost: 0 bytes in 0 blocks
==950908==    still reachable: 0 bytes in 0 blocks
==950908==         suppressed: 0 bytes in 0 blocks
==950908== 
==950908== For lists of detected and suppressed errors, rerun with: -s
==950908== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

代码

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

char* get_alphabet_array(){
    char *alpha =   (char*) malloc(sizeof(char) * 27);

    for(int i = 0; i < 27; i++) {
        if(i == 0) {
            alpha[i] = 'A';
        } else if (i < 26) {
                 alpha[i] =  alpha[i-1] + 1;
        } else if (i == 26) {
            alpha[i] = '[=13=]';
            break;
        }
       //  printf("Character at index %d is: %c\n", i, alpha[i]);
    }
    return alpha;
}

int main () {

    char* alpha = get_alphabet_array();

    while(*alpha != '[=13=]') {
        static int count = 0;
        printf("Letter at index %d: %c\n", count, *alpha);
        count++;
        *alpha++;
    }

    free(*alpha);
    return 0;
}

你是从这个开始的

char* alpha = get_alphabet_array();

while(*alpha != '[=10=]') {
    static int count = 0;
    printf("Letter at index %d: %c\n", count, *alpha);
    count++;
    *alpha++;
}

free(*alpha);    // <-- this attempts to free what `alpha` points to (not good)

它通过 free(*alpha) 尝试释放 alpha 指向的内容而不是指针 alpha。这或当然,没有意义。所以你把它改成这样:

char* alpha = get_alphabet_array();

while(*alpha != '[=11=]') {
    static int count = 0;
    printf("Letter at index %d: %c\n", count, *alpha);
    count++;
    *alpha++;   // <-- this alters the value of the pointer, `alpha`
}

free(alpha);    // <-- this frees the *altered* value of `alpha` (not good)

现在您遇到了一个不同的问题,因为 alpha 的值在您从内存分配中收到它后发生了变化,并且 free(alpha) 正在释放错误的指针值。您需要释放原始指针。例如,

char* alpha = get_alphabet_array();

for (char *p = alpha; *p != '[=12=]'; p++) {   // this loop does not alter `alpha`
    static int count = 0;
    printf("Letter at index %d: %c\n", count, *p);
    count++;
}

free(alpha);    // <-- this frees the originally allocated pointer

顺便说一句,语句 *alpha++; 递增 alpha 中的指针,然后取消引用指针并丢弃结果。所以这里的 * 并没有真正起到任何作用。