C 创建用于处理mpz_t阵列初始化和清理的函数时遇到分段错误

C 创建用于处理mpz_t阵列初始化和清理的函数时遇到分段错误,c,memory-leaks,segmentation-fault,C,Memory Leaks,Segmentation Fault,我使用GNUMP创建了一个多精度整数数组。如果我初始化、使用和清理所有主要功能,它工作得很完美,没有错误。我尝试创建辅助函数来管理重复作业:初始化数组和清理数组。不幸的是,它没有结束好,我得到了内存泄漏。我在下面举了一个小例子,再现了错误行为: #include <stdio.h> #include <stdlib.h> #include <gmp.h> mpz_t *start(int n) { mpz_t *c = malloc(n*sizeof(m

我使用GNUMP创建了一个多精度整数数组。如果我初始化、使用和清理所有主要功能,它工作得很完美,没有错误。我尝试创建辅助函数来管理重复作业:初始化数组和清理数组。不幸的是,它没有结束好,我得到了内存泄漏。我在下面举了一个小例子,再现了错误行为:

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

mpz_t *start(int n)
{
  mpz_t *c = malloc(n*sizeof(mpz_t));
  for (int i=0; i<n; i++) mpz_init (c[i]);
  for (int i=0; i<n; i++) mpz_set_ui (c[i], 1);
}

void finish(mpz_t *x, int n)
{
  for (int i=0; i<n; i++) mpz_clear (x[i]);
  free(x);
}

int main(int argc, char *argv[])
{
  int n = 10;
  mpz_t *c = start(n);
  finish(c, n);
  return 0;
}
以下是Valgrind分析日志:

==18807== Memcheck, a memory error detector
==18807== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==18807== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==18807== Command: ./test
==18807== 
==18807== Invalid read of size 4
==18807==    at 0x4887C60: __gmpz_clear (in /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2)
==18807==    by 0x10928B: finish (test.c:14)
==18807==    by 0x1092DF: main (test.c:22)
==18807==  Address 0xa is not stack'd, malloc'd or (recently) free'd
==18807== 
==18807== 
==18807== Process terminating with default action of signal 11 (SIGSEGV)
==18807==  Access not within mapped region at address 0xA
==18807==    at 0x4887C60: __gmpz_clear (in /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2)
==18807==    by 0x10928B: finish (test.c:14)
==18807==    by 0x1092DF: main (test.c:22)
==18807==  If you believe this happened as a result of a stack
==18807==  overflow in your program's main thread (unlikely but
==18807==  possible), you can try to increase the size of the
==18807==  main thread stack using the --main-stacksize= flag.
==18807==  The main thread stack size used in this run was 8388608.
==18807== 
==18807== HEAP SUMMARY:
==18807==     in use at exit: 240 bytes in 11 blocks
==18807==   total heap usage: 11 allocs, 0 frees, 240 bytes allocated
==18807== 
==18807== 240 (160 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==18807==    at 0x483A7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==18807==    by 0x1091E8: start (test.c:7)
==18807==    by 0x1092CA: main (test.c:21)
==18807== 
==18807== LEAK SUMMARY:
==18807==    definitely lost: 160 bytes in 1 blocks
==18807==    indirectly lost: 80 bytes in 10 blocks
==18807==      possibly lost: 0 bytes in 0 blocks
==18807==    still reachable: 0 bytes in 0 blocks
==18807==         suppressed: 0 bytes in 0 blocks
==18807== 
==18807== For lists of detected and suppressed errors, rerun with: -s
==18807== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

怎么了?如何修复它?

在没有返回语句的情况下从值返回函数(main除外)的末尾流出是未定义的行为

在您的示例中,
mpz\u t*start(int n)
实际上不返回任何内容,这将导致UB

==18807== Memcheck, a memory error detector
==18807== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==18807== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==18807== Command: ./test
==18807== 
==18807== Invalid read of size 4
==18807==    at 0x4887C60: __gmpz_clear (in /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2)
==18807==    by 0x10928B: finish (test.c:14)
==18807==    by 0x1092DF: main (test.c:22)
==18807==  Address 0xa is not stack'd, malloc'd or (recently) free'd
==18807== 
==18807== 
==18807== Process terminating with default action of signal 11 (SIGSEGV)
==18807==  Access not within mapped region at address 0xA
==18807==    at 0x4887C60: __gmpz_clear (in /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2)
==18807==    by 0x10928B: finish (test.c:14)
==18807==    by 0x1092DF: main (test.c:22)
==18807==  If you believe this happened as a result of a stack
==18807==  overflow in your program's main thread (unlikely but
==18807==  possible), you can try to increase the size of the
==18807==  main thread stack using the --main-stacksize= flag.
==18807==  The main thread stack size used in this run was 8388608.
==18807== 
==18807== HEAP SUMMARY:
==18807==     in use at exit: 240 bytes in 11 blocks
==18807==   total heap usage: 11 allocs, 0 frees, 240 bytes allocated
==18807== 
==18807== 240 (160 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==18807==    at 0x483A7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==18807==    by 0x1091E8: start (test.c:7)
==18807==    by 0x1092CA: main (test.c:21)
==18807== 
==18807== LEAK SUMMARY:
==18807==    definitely lost: 160 bytes in 1 blocks
==18807==    indirectly lost: 80 bytes in 10 blocks
==18807==      possibly lost: 0 bytes in 0 blocks
==18807==    still reachable: 0 bytes in 0 blocks
==18807==         suppressed: 0 bytes in 0 blocks
==18807== 
==18807== For lists of detected and suppressed errors, rerun with: -s
==18807== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)