gpt4 book ai didi

c - C免费的malloc的结构成员和结构

转载 作者:太空狗 更新时间:2023-10-29 15:36:06 26 4
gpt4 key购买 nike

当我运行试图释放此结构中的任何内容时遇到问题。首先是头中的结构定义:

    typedef struct{
int* rType;
unsigned long int numCols;
char* rString; //The literal string, NULL delimited
int rsSize; //The size of the string, since NULLS can't be used to find the string end
int* colsIndex; //Where each new column starts in rString
long* iColVals; //integer version of the column
double* dColVals; //double precision value of column
} row_t ;

下面是可以创建结构实例的位置:
row_t* delimitLine(char* line, char* delimList, char delimListSize)
{
row_t* thisRow;
.
.
.
//Make a place for this stuff in memory
thisRow = (row_t*) malloc(sizeof(row_t));
if(thisRow==NULL) return NULL;
.
.
.
thisRow->rString = line;

//Make Row Mem

//colsIndex
thisRow->colsIndex = (int*) malloc(numCols*sizeof(int));
if(thisRow->colsIndex==NULL) return NULL;

//rType
thisRow->rType = (int*) malloc(numCols*sizeof(int));
if(thisRow->rType==NULL) return NULL;

//iColVals
thisRow->iColVals = (long*) malloc(numCols*sizeof(long));
if(thisRow->iColVals==NULL) return NULL;

//dColVals
thisRow->dColVals = (double*) malloc(numCols*sizeof(double));
if(thisRow->dColVals==NULL) return NULL;
.
.
.
return thisRow;

下面是如何创建“line”的:
char* RBreadLine(fifo_t* fifo)
{
char* outbuf = NULL;
.
.
.
outbuf = (char*) malloc(sizeof(char)*(cnt+1));
.
.
.
return outbuf;
}

最后是调用序列:
main()
{
row_t* row = NULL;
.
.
.
while(kg>=0)
{
//test condition to exit loop not shown
line = RBreadLine(fifo);
.
.
.

row = delimitLine(line, delimList, delimListSize);
//some code to manipulate the row data here
printRow(row);
rowDestructor(row);



}

}

当我注释掉对rowdestructor的调用时,程序按预期运行,但如果我试图释放任何内容,程序就会崩溃。我试过注释除struct的单个成员之外的所有行,但仍然会出现崩溃,所以我在这里做了一些错误的事情。
其思想是使用一个大型文本文件处理程序逐行读取数据,让我做一些操作来处理行数据,然后printrow()输出最终结果。
简单的测试用例是在值从定界线函数(只分配内存并用数据填充行结构)出来时输出它们。
当这个过程结束时,我应该想释放内存并重新开始。如果我不调用析构函数,这个程序就会按预期工作,而只是在每次有新的rbreadline()和delimiteline()调用时孤立这些指针。
如果我调用rowDestructor(),则程序在第一行(在第一次调用rowDestructor()时)之后崩溃:
 Now to start outputting line
1) 2) 3) 4) 5) 6) 7) 8) 9) 10) (-10)63.116722551236001948 0 0 0 0 1 1 1 1 1 0 1

Aborted (core dumped)

也许我对malloc()或free()有些不理解,但似乎如果我可以从结构成员访问有效的数据而没有错误,并且不会导致崩溃,那么free应该能够释放已经malloc'd的mem。
也许我只是把这些指针到处传递(比如把指向“line”的指针传递给一个将其分配给struct成员的函数)做了一些不好的事情,但在我看来,这些指针都被很好地考虑了。我知道这个结构的每个成员都得到了malloc,所以我应该能够在工作的过程中释放它,然后释放这个结构。然后,我可以将另一个指针转储到row结构上,然后再次执行它。
我之所以这样做是因为我希望能够处理非常大的数据集。这是对一个程序的结构重写,该程序以前用fread将所有数据加载到内存中,然后对其进行处理,但我的一些数据集会导致计算机内存不足……所以我将采用块处理方法。
一旦我可以成功地释放一行,我就可以在这个基础上创建一个行,在这里我可以使用fifo缓冲区的概念将行循环到行上,这将允许我以合理的数量向前和向后搜索文本文件(比如fir过滤器的应用),但不需要将整个文件加载到内存中。
例如,行fifo将这些新的行结构存储到行上,在填充循环缓冲区并开始覆盖旧指针之后释放旧的行结构……这就是我要做的。
我认为对这个问题的回答将是我对malloc()和free()理解的一个突破,或者可能会澄清一些关于指针和结构的问题。
谢谢你的意见。
编辑:
我很抱歉忽略了我问题中最重要的部分:
void rowDestructor(row_t* thisRow)
{
//rString
free(thisRow->rString);

//colsIndex
free(thisRow->colsIndex);

//rType
free(thisRow->rType);

//iColVals
free(thisRow->iColVals);

//dColVals
free(thisRow->dColVals);

//finally kill the whole thing
free(thisRow);
}

而且,由于其他人提到了编译器标志,下面是我使用的:
gcc  -Wall laproc.c utils.c csvsurgeon.c -lm -o csv-surgeon

(laproc.c是我需要与math lib链接的特定信号处理代码,在本例中,我将其简化为不调用这些函数来排除它们)
我正在使用此版本的gcc:
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-cygwin/4.5.3/lto-wrapper.exe
Target: i686-pc-cygwin
Configured with: /gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gcc-4.5.3/configure --srcdir=/gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gc
c-4.5.3 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --datadir=/usr/share --localstatedir=/var --sysco
nfdir=/etc --datarootdir=/usr/share --docdir=/usr/share/doc/gcc4 -C --datadir=/usr/share --infodir=/usr/share/info --mandir=/usr/share/man -v --with-g
mp=/usr --with-mpfr=/usr --enable-bootstrap --enable-version-specific-runtime-libs --libexecdir=/usr/lib --enable-static --enable-shared --enable-shar
ed-libgcc --disable-__cxa_atexit --with-gnu-ld --with-gnu-as --with-dwarf2 --disable-sjlj-exceptions --enable-languages=ada,c,c++,fortran,java,lto,obj
c,obj-c++ --enable-graphite --enable-lto --enable-java-awt=gtk --disable-symvers --enable-libjava --program-suffix=-4 --enable-libgomp --enable-libssp
--enable-libada --enable-threads=posix --with-arch=i686 --with-tune=generic --enable-libgcj-sublibs CC=gcc-4 CXX=g++-4 CC_FOR_TARGET=gcc-4 CXX_FOR_TA
RGET=g++-4 GNATMAKE_FOR_TARGET=gnatmake GNATBIND_FOR_TARGET=gnatbind --with-ecj-jar=/usr/share/java/ecj.jar
Thread model: posix
gcc version 4.5.3 (GCC)

也许那是我的问题…
我重新编译了其他gcc版本:
Using built-in specs.
COLLECT_GCC=C:\Program Files\CodeBlocks\MinGW-newer\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/program files/codeblocks/mingw-newer/bin/../libexec/gcc/mingw32/4.5.2/lto-wrapper.exe
Target: mingw32
Configured with: ../../src/gcc-4.5.2/configure --build=mingw32 --enable-languages=c,c++,ada,fortran,objc,obj-c++ --enable-threads=win32 --enable-libgo
mp --enable-lto --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gnu-ld --disable-nls --disable-wi
n32-registry --disable-symvers --disable-werror --prefix=/mingw32tdm --with-local-prefix=/mingw32tdm --enable-cxx-flags='-fno-function-sections -fno-d
ata-sections' --with-pkgversion=tdm-1 --enable-sjlj-exceptions --with-bugurl=http://tdm-gcc.tdragon.net/bugs
Thread model: win32
gcc version 4.5.2 (tdm-1)

还有另一个版本
Using built-in specs.
Target: mingw32
Configured with: ../../gcc-4.4.1/configure --prefix=/mingw --build=mingw32 --enable-languages=c,ada,c++,fortran,objc,obj-c++ --disable-nls --disable-w
in32-registry --enable-libgomp --enable-cxx-flags='-fno-function-sections -fno-data-sections' --disable-werror --enable-threads --disable-symvers --en
able-version-specific-runtime-libs --enable-fully-dynamic-string --with-pkgversion='TDM-2 mingw32' --enable-sjlj-exceptions --with-bugurl=http://www.t
dragon.net/recentgcc/bugs.php
Thread model: win32
gcc version 4.4.1 (TDM-2 mingw32)

对于4.4.1版本,它将在运行中的不同点上隔离故障。在几次运行中,它甚至在没有seg错误的情况下完成了一次,所以我可能遇到了编译器问题。因为我有CygWin,编译器可能是混合公用程序和链接器(使用“/bin”的错误目录)。
我希望我已经包含了足够多的内容,可以清楚地说明我正在使用这些malloc的指针做什么,因为我已经包含了rowdestructor()代码。谢谢你到目前为止的评论。
如果我的c实现本身有什么问题,我想修复它。同时,我将清理我的开发环境,看看是否可以通过确保所有组件的正确路径来获得更好的结果。

最佳答案

结果发现我的记忆管理很好(难怪我把头发拔了)。我在linux上编译了这个程序,很快发现在分配内存时出现了一个“逐个关闭”的错误,因此我访问了一些超出范围的内存。在Linux机器上,程序故障是立即发生的,而Windows会让程序运行一段时间,然后终止它。
问题出在这里,对那些感兴趣的人来说:

 row_t* delimitLine(char* line, char* delimList, char delimListSize)
{
//<Analyze "line" to count number of data fields>
.
.
.

就是这样做的:
//Populate Row Data 
thisRow->numCols = numCols+1;

这就是它的修复方法:
//Populate Row Data 
numCols+=1;
thisRow->numCols = numCols;

这里有一个关于为什么这是个问题的提示
.
.
.
//colsIndex
thisRow->colsIndex = (int*) malloc(numCols*sizeof(int));
if(thisRow->colsIndex==NULL) return NULL;

//rType
thisRow->rType = (int*) malloc(numCols*sizeof(int));
if(thisRow->rType==NULL) return NULL;

//iColVals
thisRow->iColVals = (long*) malloc(numCols*sizeof(long));
if(thisRow->iColVals==NULL) return NULL;

//dColVals
thisRow->dColVals = (double*) malloc(numCols*sizeof(double));
if(thisRow->dColVals==NULL) return NULL;

该行->numcols稍后将在程序中用于访问内存,而内存已分配了“numcols”,这将是比程序试图访问的内容少一个元素。
显然,错误的内存访问给free()释放内存带来了一些麻烦。有趣的是,在Linux系统中,这会立即产生一个分段错误,这就是为什么我能够更容易地集中精力处理这个问题。
我可以把这归因于我了解到,有时候在问问题时,甚至张贴“不相关”的代码也很重要。
我自己解决的,但感谢大家的投入。事实上,没有人指出一个明显的“有你的缺陷”,这促使我深入挖掘,并评论没有在这里张贴的部分代码。

关于c - C免费的malloc的结构成员和结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16952314/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com