分配数组C时检测到堆栈崩溃
正如标题所解释的那样。在我的程序中的这个函数中,每当我在数组中分配一定的大小时,终端上就会出现大量的错误代码。数组被正确复制,但在打印后程序崩溃。该程序的目的是从文件中读取数据,然后将每一行存储在数组索引中。非常感谢你的帮助。谢谢 数组在main中声明为指针,然后在内部动态分配分配数组C时检测到堆栈崩溃,c,stack-overflow,C,Stack Overflow,正如标题所解释的那样。在我的程序中的这个函数中,每当我在数组中分配一定的大小时,终端上就会出现大量的错误代码。数组被正确复制,但在打印后程序崩溃。该程序的目的是从文件中读取数据,然后将每一行存储在数组索引中。非常感谢你的帮助。谢谢 数组在main中声明为指针,然后在内部动态分配 void read_file_into_array(char **filearray, FILE * fp) { /* use get line to count # of
void read_file_into_array(char **filearray, FILE * fp)
{
/* use get line to count # of lines */
int numlines = -1;
numlines = linecount(fp);
size_t size = 50;
char *buffer;
buffer = (char *)malloc(size * sizeof(char));
if (buffer == NULL) {
perror("Unable to allocate buffer");
exit(1);
}
if (numlines < 0) {
fprintf(stderr, "error: unable to determine file length.\n");
return;
}
printf(" number of lines counted are ; %d\n", numlines);
/* allocate array of size numlines + 1 */
if (!(*filearray = (char *)malloc(numlines + 1 * sizeof(char)))) {
fprintf(stderr, "error: virtual memory exhausted.\n");
return;
}
fseek(fp, 0, SEEK_SET);
for (int i = 0; i < numlines; i++) {
if (!feof(fp)) {
fgets(buffer, size, fp);
filearray[i] = (char *)malloc(size * sizeof(char *));
strcpy(filearray[i], buffer);
printf("buffer at %d : %s\n", i, buffer);
printf("array at %d : %s\n", i, filearray[i]);
}
}
free(buffer);
}
/* THIS IS MY MAIN BELOW */
int main (int argc, char **argv)
{
FILE *fp = NULL;
char* array;
/* open file for reading (default stdin) */
fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open */
fprintf (stderr, "error: file open failed '%s'\n", argv[1]);
return 1;
}
read_file_into_array (&array, fp);
if (fp != stdout)
if (fclose (fp) == EOF) {
fprintf (stderr, "error: fclose() returned EOF\n");
return 1;
}
return 0;
}
/* MY LNE COUNT FUNCITON */
int linecount(FILE *fp) {
char buff[MAXLINE];
int count = 0;
while(fgets(buff,MAXLINE,fp) != NULL) {
count++;
}
return count;
}
void将文件读入数组(char**filearray,file*fp)
{
/*使用get line计算行数*/
int numlines=-1;
numlines=行数(fp);
尺寸=50;
字符*缓冲区;
缓冲区=(char*)malloc(size*sizeof(char));
if(buffer==NULL){
perror(“无法分配缓冲区”);
出口(1);
}
if(numlines<0){
fprintf(stderr,“错误:无法确定文件长度。\n”);
返回;
}
printf(“计数的行数为;%d\n”,numlines);
/*分配大小为numlines+1的数组*/
如果(!(*filearray=(char*)malloc(numlines+1*sizeof(char))){
fprintf(stderr,“错误:虚拟内存耗尽。\n”);
返回;
}
fseek(fp,0,SEEK_集);
对于(int i=0;i1?fopen(argv[1],“r”):stdin;
如果(!fp){/*验证文件打开*/
fprintf(stderr,“错误:文件打开失败“%s”\n”,argv[1]);
返回1;
}
将\u文件\u读入\u数组(&array,fp);
如果(fp!=stdout)
如果(fclose(fp)=EOF){
fprintf(stderr,“错误:fclose()返回EOF\n”);
返回1;
}
返回0;
}
/*我的LNE计数函数*/
整数行数(文件*fp){
字符buff[MAXLINE];
整数计数=0;
while(fgets(buff,MAXLINE,fp)!=NULL){
计数++;
}
返回计数;
}
为什么会出现编译警告(注意指出代码中其他不同错误的注释)的一个主要问题是
if(!(*filearray=(char**)malloc(sizeof(char*)*(numlines+1))
*filearray
的类型为char*
而不是char**代码>+无需强制转换malloc
返回的值
char**filearray
实际上是定义为char*数组的main()
中的&array
代码>
现在,以下内容完全破坏了稳定性,并导致未定义的行为
filearray[i] = (char *)malloc(size * sizeof(char *));
这相当于(&array)[i]=(char*)malloc(size*sizeof(char*))代码>从主目录中,这是完全损坏的。您正在遍历堆栈,从main
的数组的位置开始,只需使用malloc
返回的char*
值覆盖所有内容
如果您希望您的数组
是字符串数组,请将其定义为字符**数组
,通过指针和数组
传递它,相应地更新文件数组
的声明和用法。好的,让我们来整理一下。首先,要将指向char的指针的指针作为参数传递给函数,请在函数内进行分配,并将结果返回调用函数中(无更多),必须传递指向char的指针的地址。否则,函数将接收一个副本,并且在调用方(main
此处)中对函数所做的任何更改都不可用,因为当函数返回时副本丢失(分配块开始的地址丢失)
将指针的地址传递给指向char的指针意味着您必须成为一名三星级程序员(这不是恭维)。更好的方法是根本不传递指针,只需在函数中分配并返回一个指向调用者的指针(但在某些情况下,仍然需要将其作为参数传递,如下所示)
下面的程序将读取作为第一个参数传递的任何文本文件(或者,如果没有给出参数,它将从stdin
读取)。它将动态分配指针和所需的指针(在MAXL
块中,而不是一次分配一个指针,这是非常低效的)。它将根据需要分配(和重新分配)线路,以适应任何长度的线路。它使用MAXC
chars的固定缓冲区连续读取,直到读取完一行,将偏移量保存到当前行中的位置,以便根据需要追加后续读取
最后,在读取文件后,它会将文本和相关行号打印到stdout
,并在退出之前释放所有分配的内存。请仔细查看,如果您有任何问题,请告诉我:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXL = 32, MAXC = 1024 };
char **read_file_into_buf (char ***buf, FILE *fp, int *nlines);
int main (int argc, char **argv) {
char **buf = NULL; /* buffer to hold lines of file */
int n; /* number of lines read */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
if (read_file_into_buf (&buf, fp, &n)) { /* read file into buf */
for (int i = 0; i < n; i++) { /* loop over all lines */
printf ("line[%3d]: %s\n", i, buf[i]); /* output line */
free (buf[i]); /* free line */
}
free (buf); /* free buffer */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
/** read text file from 'fp' into 'buf' update 'nlines'.
* Being a 3-STAR Programmer, is NOT a compliment. However,
* to pass a pointer to pointer to char as a parameter and
* allocate within the function, it is required. You must
* pass the address of buf from main otherwise the function
* recieves a copy whose allocation is lost on return. A better
* approach is to simply assign the return in 'main' and not
* pass buf at all.
*/
char **read_file_into_buf (char ***buf, FILE *fp, int *nlines)
{
/* current allocation, current index, and offset (if less
* than a whole line is read into line on fgets call), and
* eol indicates '\n' present.
*/
size_t n = MAXL, idx = 0, offset = 0, eol = 0;
char line[MAXC] = ""; /* temp buffer for MAXC chars */
void *tmp = NULL; /* pointer for realloc */
/* validate address, file ptr & nlines address */
if (!buf || !fp || !nlines) {
fprintf (stderr, "error; invalid parameter.\n");
return NULL;
}
/* allocate initial MAXL pointers, calloc used to avoid valgrind
* warning about basing a conditional jump on uninitialized value.
* calloc allocates and initializes.
*/
if (!(*buf = calloc (sizeof *buf, MAXL))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return NULL;
}
while (fgets (line, MAXC, fp)) /* read every line in file */
{
/* save offset from prior read (if any), get len */
size_t end = offset, len = strlen (line);
if (line[len - 1] == '\n') { /* test for new line */
line[--len] = 0; /* overwrite with nul */
offset = 0; /* zero offset, all read */
eol = 1; /* POSIX eol present */
}
else {
line[len] = 0; /* nul-terminate */
offset += len; /* short read, save offset to last char */
eol = 0; /* no POSIX eol */
}
/* allocate/reallocate for current line + nul-byte */
tmp = realloc ((*buf)[idx], sizeof ***buf * (end + len + 1));
if (!tmp) {
fprintf (stderr, "error: realloc, memory exhausted.\n");
return *buf; /* return current buf */
}
(*buf)[idx] = tmp; /* assign block to current index */
strcpy ((*buf)[idx] + end, line); /* copy line to block */
if (!eol) continue; /* chars remain in line, go read them */
if (++idx == n) { /* check pointer allocation, realloc as needed */
tmp = realloc (*buf, sizeof **buf * (n + MAXL));
if (!tmp) {
fprintf (stderr, "error: realloc buf, memory exhausted.\n");
return *buf;
}
*buf = tmp; /* assign new block to *buf */
memset (*buf + n, 0, sizeof **buf * MAXL); /* zero new memory */
n += MAXL; /* update the current number of ptrs allocated */
}
*nlines = idx; /* update the number of lines read */
}
if (!eol) { /* protect against file with no POSIX ending '\n' */
idx++; /* account for final line */
*nlines = idx; /* update nlines */
}
/* final realloc to size buf to exactly fit number of lines */
tmp = realloc (*buf, sizeof **buf * (idx));
if (!tmp) /* if it fails, return current buf */
return *buf;
*buf = tmp; /* assign reallocated block to buf */
return *buf;
}
在您编写的任何动态分配内存的代码中,对于分配的任何内存块,您有两个责任:(1)始终保留指向内存块起始地址的指针,以便(2)它可以是fr
$ ./bin/fgets_readfile < dat/damages.txt
line[ 0]: Personal injury damage awards are unliquidated
line[ 1]: and are not capable of certain measurement; thus, the
line[ 2]: jury has broad discretion in assessing the amount of
line[ 3]: damages in a personal injury case. Yet, at the same
line[ 4]: time, a factual sufficiency review insures that the
line[ 5]: evidence supports the jury's award; and, although
line[ 6]: difficult, the law requires appellate courts to conduct
line[ 7]: factual sufficiency reviews on damage awards in
line[ 8]: personal injury cases. Thus, while a jury has latitude in
line[ 9]: assessing intangible damages in personal injury cases,
line[ 10]: a jury's damage award does not escape the scrutiny of
line[ 11]: appellate review.
line[ 12]:
line[ 13]: Because Texas law applies no physical manifestation
line[ 14]: rule to restrict wrongful death recoveries, a
line[ 15]: trial court in a death case is prudent when it chooses
line[ 16]: to submit the issues of mental anguish and loss of
line[ 17]: society and companionship. While there is a
line[ 18]: presumption of mental anguish for the wrongful death
line[ 19]: beneficiary, the Texas Supreme Court has not indicated
line[ 20]: that reviewing courts should presume that the mental
line[ 21]: anguish is sufficient to support a large award. Testimony
line[ 22]: that proves the beneficiary suffered severe mental
line[ 23]: anguish or severe grief should be a significant and
line[ 24]: sometimes determining factor in a factual sufficiency
line[ 25]: analysis of large non-pecuniary damage awards.
$ valgrind ./bin/fgets_readfile < dat/damages.txt
==5863== Memcheck, a memory error detector
==5863== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5863== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==5863== Command: ./bin/fgets_readfile
==5863==
line[ 0]: Personal injury damage awards are unliquidated
line[ 1]: and are not capable of certain measurement; thus, the
line[ 2]: jury has broad discretion in assessing the amount of
line[ 3]: damages in a personal injury case. Yet, at the same
line[ 4]: time, a factual sufficiency review insures that the
line[ 5]: evidence supports the jury's award; and, although
line[ 6]: difficult, the law requires appellate courts to conduct
line[ 7]: factual sufficiency reviews on damage awards in
line[ 8]: personal injury cases. Thus, while a jury has latitude in
line[ 9]: assessing intangible damages in personal injury cases,
line[ 10]: a jury's damage award does not escape the scrutiny of
line[ 11]: appellate review.
line[ 12]:
line[ 13]: Because Texas law applies no physical manifestation
line[ 14]: rule to restrict wrongful death recoveries, a
line[ 15]: trial court in a death case is prudent when it chooses
line[ 16]: to submit the issues of mental anguish and loss of
line[ 17]: society and companionship. While there is a
line[ 18]: presumption of mental anguish for the wrongful death
line[ 19]: beneficiary, the Texas Supreme Court has not indicated
line[ 20]: that reviewing courts should presume that the mental
line[ 21]: anguish is sufficient to support a large award. Testimony
line[ 22]: that proves the beneficiary suffered severe mental
line[ 23]: anguish or severe grief should be a significant and
line[ 24]: sometimes determining factor in a factual sufficiency
line[ 25]: analysis of large non-pecuniary damage awards.
==5863==
==5863== HEAP SUMMARY:
==5863== in use at exit: 0 bytes in 0 blocks
==5863== total heap usage: 28 allocs, 28 frees, 1,733 bytes allocated
==5863==
==5863== All heap blocks were freed -- no leaks are possible
==5863==
==5863== For counts of detected and suppressed errors, rerun with: -v
==5863== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)