- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
又是realloc的问题。看来我在之前的很多realloc语句中都没有发现类似的问题。我将不胜感激您的兴趣。
我正在尝试读取格式的文本输入: g:<expression>;0,1,0,1,0
。我在源文本文件中有一组这种格式的行,以及在“for”循环中读取此行的代码片段(如下)。 :
之间的表达式和;
被读入propstr
二维字符数组。 ;
之后的一切确定由逗号分隔的数字组成的 vector (大小为 DIM
) ,
。该 vector 被读入 upstr
(就像一个字符串)然后转换为整数数组 upvec
按功能process_update_vector
。在循环的每次迭代 realloc
用于调整上述数组的大小( propstr
、 upstr
和 upvec
)。到目前为止在循环中读取的行数是 NREAC
。这是代码:
/*Before this point, current line in the source is read into `temp'*/
NREAC++;
for(i=0;i<strlen(temp);i++){
if(temp[i]==':') colon=i;//Here we find colon
if(temp[i]==';') semicolon=i;//...and semicolon positions
}
memset(temp1,'\0',STRLEN);
if(NREAC==1)
ptrchar=(char **)malloc(sizeof(char *));
else
ptrchar=realloc(propstr,NREAC*sizeof(char *));
if(ptrchar==NULL){
fprintf(stderr,"Error: could not allocate memory for propstr\n");
if(propstr!=NULL) free(propstr);
return 1345;
}else{propstr=ptrchar;ptrchar=NULL;}
propstr[NREAC-1]=(char *)malloc((semicolon-colon)*sizeof(char));
if(propstr[NREAC-1]==NULL){
fprintf(stderr,"Error: couldn't get memory for propstr[NREAC-1]\n");
return 1344;
}
for(i=colon+1;i<semicolon;i++)/*Copy the propensity part of the line*/
temp1[i-colon-1]=temp[i];
temp1[i-colon-1]='\n';/*Include newline symbol for correct parsing*/
strcpy(propstr[NREAC-1],temp1);
memset(temp1,'\0',STRLEN);
if(NREAC==1)
ptrchar=(char **)malloc(sizeof(char *));
else
ptrchar=realloc(upstr,NREAC*sizeof(char *));
if(ptrchar==NULL){
fprintf(stderr,"Error could not allocate memory for upstr\n");
if(upstr!=NULL) free(upstr);
return 1343;
}else{upstr=ptrchar;ptrchar=NULL;}
upstr[NREAC-1]=(char *)malloc((strlen(temp)-semicolon-1)*sizeof(char));
if(upstr[NREAC-1]==NULL){
fprintf(stderr,"Error: couldn't get memory for upstr[NREAC-1]\n");
return 1342;
}
if(strlen(temp)-semicolon==2){/*No vector is specified*/
fprintf(stderr,"Error: no update vector found:\n");
fprintf(stderr,"`%s'",temp);
return 1;
}
if(NREAC==1)
ptrint=(int **)malloc(sizeof(int *));
else
ptrint=(int **)realloc(upvec,NREAC*(sizeof(int *)));/*!!!!!!!!!!!!!!!!!!!!*/
if(ptrint==NULL){
fprintf(stderr,"Error: could not allocate memory for upvec\n");
if(upvec!=NULL) free(upvec);
return 1341;
}else{upvec=ptrint;ptrint=NULL;}
upvec[NREAC-1]=(int *)malloc(DIM*sizeof(int));
if(upvec[NREAC-1]==NULL){
fprintf(stderr,"Error: couldn't get memory for upvec[NREAC-1]\n");
return 1340;
}
for(i=semicolon+1;i<strlen(temp)-1;i++)
temp1[i-semicolon-1]=temp[i];
temp1[i-semicolon-1]='\n';/*Include newline for more convenient way of parsing*/
strcpy(upstr[NREAC-1],temp1);
/*Get update vector*/
upvec[NREAC-1]=process_update_vector(upstr[NREAC-1],upvec[NREAC-1]);
memset(temp1,'\0',STRLEN);
memset(temp,'\0',STRLEN);
continue;
该片段出现在 for 循环中。在标有 /*!!!!!!!!!!!!!!!!!!!!*/
的地方出现“无效指针”错误。 .
错误的情况。对于足够小的DIM
一切都很好并且总是有效。在某些时候,我不得不增加 DIM
最多 11,然后在解析过程中间发生错误(我猜这是常见错误 *** glibc detected *** dinamica: realloc(): invalid pointer: 0x000000000165d190 ***
)。 NREAC
的值似乎不影响重新分配行为。它始终是代码中发生错误的同一位置。我是否错误地将内存分配给 int
类型变量,因为 char
的分配类型从来都不是问题?
process_update_vector
功能:
int * process_update_vector(const char *upstr,int *upvec)
{
int i,j,k;
char symbuf[5];/*5 symbols, max 99999 is possible*/
i = 0;
j = 0;
k = 0;
while(upstr[i] != '\n'){
if(upstr[i] == ','){/*',' is the delimiter*/
symbuf[j] = '\0';
j = 0;
upvec[k] = atoi(symbuf);
k++;
i++;
continue;
}
symbuf[j] = upstr[i];
j++;
i++;
}
/*For the last entry*/
upvec[k] = atoi(symbuf);
k++;
return upvec;
}
最佳答案
好的,我试着看看你的代码。我的眼睛很酸,但我还是成功地通过了代码。这是我对第一部分的更改,您可以在其中阅读冒号和分号之间的表达式。我更改了一些类型,但让或多或少相同的错误处理,即使我认为这是矫枉过正或者更好地说,它位于错误的位置(我倾向于将分配/错误工作与业务代码分开,使得更容易调试)。
/*Before this point, current line in the source is read into `temp'*/
char **propstr=NULL; /* I hope this variable was initialized to NULL or else you get problems */
NREAC++; /* This is bad naming, all uppercase is by convention reserved for macros */
char *colon = strchr(temp, ':'); /* There a lib function to do the searching, use them */
char *semicolon = strchr(temp, ';');
if(!colon || !semicolon) {
fprintf(stderr,"Error: syntax error\n");
return 2112; /* whatever */
}
ptrchar=realloc(propstr,NREAC*sizeof(char *)); /* realloc called with a NULL pointer is the same as a malloc, typecasts of mallocs/reallocs are not good. */
if(!ptrchar) {
fprintf(stderr,"Error: could not allocate memory for propstr\n");
free(propstr); /* The check against NULL is also done by free, it's therefoe redundant */
return 1345;
}
else
propstr=ptrchar; /* There's no point in NULLing a variable that will be overwritten anyway */
size_t lenexpr = semicolon-colon; /* The length of the expression can be found by subtracting both pointers */
propstr[NREAC-1]=malloc(lenexpr+1); /* +1 for the \n */
if(!propstr[NREAC-1]) {
fprintf(stderr,"Error: couldn't get memory for propstr[NREAC-1]\n");
return 1344;
}
memcpy(propstr[NREAC-1], colon+1, lenexpr); /* We copy directly without a temporary that way */
propstr[NREAC-1][lenexpr] = '\n'; /* add the linefeed */
propstr[NREAC-1][lenexpr+1] = 0; /* terminate the string */
在这里我停了下来,因为你的第二部分有一个我不明白的根本错误。您想将 vector 存储为字符串还是整数数组。如果是前者,那么您必须分配字符而不是 sizeof (int)
,如果是后者,一定有一些atoi
或strtol
某处。
当您向 SO 提交问题时,还有其他一些事情会很好,您应该包括您使用的变量的声明,您应该显示您使用的宏的定义。
编辑:第二部分
// Edit3 ptrchar=realloc(upstr, NREAC*sizeof(char *));
// Edit3 if(!ptrchar) {
// Edit3 fprintf(stderr,"Error could not allocate memory for upstr\n");
// Edit3 free(upstr);
// Edit3 return 1343;
// Edit3 }
// Edit3 else
// Edit3 upstr=ptrchar;
// Edit3 upstr[NREAC-1] = malloc(strlen(semicolon)+1); /* +1 for the \n */
// Edit3 if(!upstr[NREAC-1]) {
// Edit3 fprintf(stderr,"Error: couldn't get memory for upstr[NREAC-1]\n");
// Edit3 return 1342;
// Edit3 }
if(strlen(semicolon)<2) {/*No vector is specified*/
fprintf(stderr,"Error: no update vector found:\n'%s'", temp);
return 1;
}
ptrint = realloc(upvec, NREAC*sizeof(int *));/*!!!!!!!!!!!!!!!!!!!!*/
if(!ptrint) {
fprintf(stderr,"Error: could not allocate memory for upvec\n");
free(upvec);
return 1341;
}
else
upvec=ptrint;
upvec[NREAC-1] = malloc(DIM*sizeof(int));
if(!upvec[NREAC-1]) {
fprintf(stderr,"Error: couldn't get memory for upvec[NREAC-1]\n");
return 1340;
}
// Edit3 memcpy(upstr[NREAC-1], semicolon+1, strlen(semicolon+1)+1); /* +1 will include the \0 */
// Edit3 strcat(upstr[NREAC-1], "\n"); /*Include newline for more convenient way of parsing*/
/*Get update vector*/
// Edit3 upvec[NREAC-1] = process_update_vector(upstr[NREAC-1], upvec[NREAC-1]);
// Edit3, let's reuse our initial pointer, it's still valid.
process_update_vector(semicolon+1, upvec[NREAC-1]);
continue;
该函数的签名process_update_vector
看起来很奇怪,它是否重新分配upvec[NREAC-1]
?如果不是,则返回它并重新分配它是没有意义的。因此,最好也展示该功能。
结论:我在您的代码中检测到的唯一错误是,由于附加的\n,分配的长度 1 太短。其他点:通过替换if(first) malloc else realloc
通过我的realloc
您必须确保该指针最初为 NULL,否则就会出现问题。
编辑2:这里是process_update_vector的更新版本,本身并没有错误,但它的作用有点复杂。它还具有很高的缓冲区溢出风险,临时缓冲区只有 5 个字符!
此版本不需要临时缓冲区。
void process_update_vector(const char *upstr, int *upvec)
{
const char *p = strchr(upstr, ','); /* There are fine library functions for string handling */
int k = 0;
while(p) {
upvec[k++] = atoi(upstr);
upstr = p+1; /* Position upstr to after , */
p = strchr(upstr, ',');
}
upvec[k++] = atoi(upstr);
/* We don't need to return upvec, it doesn't change in the function */
}
两条评论:- 没有对 DIM 进行检查,因此在输入损坏时我们可能会出现缓冲区溢出。- 没有任何空格处理,通常在逗号后输入字符串(它更具可读性),这种情况在这种情况下不起作用,但有几个 while(*p==' ') p++;
放置在正确的位置可以解决这个问题。
编辑3:被调用函数的变化也会改变调用者,不需要复制到upstr,这样就可以完全删除分配。我添加了// Edit3
第二条 list 中的评论。当然,除非您打算在其他地方重复使用复制的字符串。
PS:在此,感谢是通过对答案进行投票来完成的。
关于c - 重新分配(再次),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13049079/
之前有人问过这个问题,但是当移动到具有相反字节序的平台(在这种情况下从大到小)时,我仍然对如何处理位域结构感到有些困惑。所以如果我有这个: typedef struct { unsigned
我之前问过这个问题here , 但它被标记为重复并已关闭。不幸的是,我被指出的答案不起作用.... 所以,再次: 我可以生成一个像这样的 eCharts4r 仪表 library(echarts4r)
关于 .NET 中对不可为空引用类型的支持存在很多问题。最大的希望是代码契约,但它仅限于对预算有限的人进行运行时检查。 对于代码契约以外的方法,Jon Skeet 写了一篇 blog post几年前,
当我通过将终止标志设置为true来停止线程'srch_slave_thread'时,(srch_slave_thread.terminate)释放线程的线程停止在析构函数的'inherited'行中,
We know that Windows 使用 CR + LF 对作为换行符,Unix(包括 Linux 和 OS X)使用单个 LF,而 MacOS 使用单个 CR。 这是否意味着 C 和 C++
This other SO question询问 WPF 中的自动完成文本框。有几个人已经构建了这些,其中给出的答案之一表明 this codeproject article . 但我还没有找到任何与
这个问题对我来说就像是噩梦的重演。该项目是使用 gpt3 训练聊天机器人,我正在试验嵌入。 我有文档,我正在尝试为不同的部分创建嵌入。根据我的测试,getEmbeddings() 似乎返回了一个值。但
我收到数据读取器初始化错误。我知道这个问题以前已经回答过很多次了,但这些案例似乎不适合我的情况。错误消息开头为“执行读取器:连接属性尚未初始化。” 程序: using System; using Sy
我知道这个问题已被多次询问和回答,但我正在抓狂,因为所提出的解决方案似乎都不起作用。 尽管有一个有效的配置文件,据我所知,它与 bundle 标识符匹配,但我收到了上述错误: 我已按照本网站上各种建议
所以我有一个小问题 这是我的文字 AFTER_2011/03/01 GREATER_2004_NOT 我想要 AFTER 和 GREATER,所以我有以下正则表达式: [A-Z]{2,}\\B 一开始
这个问题对我来说就像是噩梦的重演。该项目是使用 gpt3 训练聊天机器人,我正在试验嵌入。 我有文档,我正在尝试为不同的部分创建嵌入。根据我的测试,getEmbeddings() 似乎返回了一个值。但
我目前正在做具有图形功能的计算器应用程序。然后,我在我的计算器中有这个按钮,并将它连接到我的 Calculator2ViewController 上。此外,我将此按钮连接到另一个名为 GraphVie
昨天,我尝试以一种方式执行此操作...今天我尝试另一种方式,但仍然卡住了。我必须找到一种使用整数除法和取模来做到这一点的方法。这是我的代码,后面是错误消息。 public int evaluateFr
我大致正在处理以下内容: var i; var k = 5; $('document').ready(function () { $('#someElement').click(functio
又是realloc的问题。看来我在之前的很多realloc语句中都没有发现类似的问题。我将不胜感激您的兴趣。 我正在尝试读取格式的文本输入: g:;0,1,0,1,0 。我在源文本文件中有一组这种格式
我不知道为什么下面会给我:*“error LNK2001: unresolved external symbol 'struct Win32Vars_t win32' (?win32@@3UWin32
又是我。在我所有的问题中,我认为这是所有问题中最愚蠢的,但由于疲劳或愚蠢,我也需要一些帮助。然而,最重要的是,我这样做是为了我的一项任务,并且有一个严格的规则 - 我必须使用一个函数调用 char*
在 Ubuntu 14.04.5 上运行 MySql 5.5.53。当从文本文件导入数据时(加载数据 infil $FIL INTO TABLE &c),我收到可怕的提示,因为 secure_file
我在 Stackoverflow 中找到了大量关于如何选择组中第一行和最后一行的示例,但我无法根据需要调整它们。唉,我对 MySQL 的有限了解无济于事。 一些数据(date_time、val1 和
我遇到错误“连接必须有效并再次打开,当我更改我的 sql 查询代码时。任何人都可以帮忙吗??(编辑)在 form1 中我已经连接到数据库,在 form2 中我试图添加查询。 //IN Class1.c
我是一名优秀的程序员,十分优秀!