以前工作的功能,突然拒绝合作。更准确地说,这个片段:
//If not, add to UIDS
printf("line 78\n");
free(s2);
printf("line 82\n");
char * ss = malloc(snprintf(NULL, 0, "%s:%d", myUIDs, userId) + 1);
printf("line 84\n");
sprintf(ss, "%s:%d", myUIDs, userId);
free(myUIDs);
myUIDs=ss;
free(buffer);
程序在“第82行”(不再是第82行,但只是一个调试停止)之后使用Segmentation Fault (core dumped)
失败了一行。
如果我改变
char * ss = malloc(snprintf(NULL, 0, "%s:%d", myUIDs, userId) + 1);
到
char * ss = malloc(snprintf(NULL, 0, "%s:%d", "", 1) + 1);
我得到了Bus Error: Code dumped
。我正在研究这个程序很长一段时间,我觉得这很明显,我因为精疲力竭而不断忽视,但此时没有程序员朋友请求帮助。
上下文的整个功能:
char* myUIDs; //string containing all UID-s, separated by colon
void printProcessInformation(char pid[],int isSetP, int isSetN, int isSetU){
//find full path name to your "stat" file
//DIR *dir;
//struct dirent *ent;
//Creating string with /proc/PID
char * s = malloc(snprintf(NULL, 0, "%s%s", "/proc/", pid) + 1);
sprintf(s, "%s%s", "/proc/", pid);
//Creating string with /proc/PID/psinfo (full path)
char * fullPath = malloc(snprintf(NULL, 0, "%s%s", s, "/psinfo") + 1);
sprintf(fullPath, "%s%s", s, "/psinfo");
free(s);
//printf("%s\n",fullPath);
//Reading data from file
FILE* file = fopen(fullPath, "r");
printf("line 37\n");
char* buffer;
buffer = (char*) malloc(sizeof(psinfo_t));
printf("line 40\n");
if(file == NULL)
{
//perror("Error: Couldn't open file");
return;
}
fread((void *)buffer, sizeof(psinfo_t), 1, file);
psinfo_t* pData = (psinfo_t*) buffer;
time_t sTime=pData->pr_start.tv_sec;
int pr_pid=pData->pr_pid;
char* fname=pData->pr_fname;
free(buffer);
buffer = (char*) malloc(sizeof(stat));
stat(fullPath,buffer);
struct stat* fileStat=(struct stat*) buffer;
fclose(file);
int userId=fileStat->st_uid;
struct passwd* pw=getpwuid(userId);
char* uid=pw->pw_name;
printf("line 58\n");
if(isSetU<0){
//Print results
printf("%8s", uid);
if(isSetP>0)
printf(" %5d",pr_pid);
printf(" %16s %.24s\n", fname, ctime(&sTime));
free(buffer);
}else{
//Or else, add UID to UIDS if it didn't appear before
//check if UID is in UIDS
printf("line 70\n");
char * s2 = malloc(snprintf(NULL, 0, "%s:%d", "", userId) + 1);
printf("line 72\n");
snprintf(s2, "%s:%d", "", userId);
if(strstr(myUIDs,s2)!=NULL){
free(s2);
free(buffer);
return;
}
//If not, add to UIDS
printf("line 78\n");
free(s2);
printf("line 82\n");
char * ss = malloc(snprintf(NULL, 0, "%s:%d", "", 1) + 1);
printf("line 84\n");
sprintf(ss, "%s:%d", myUIDs, userId);
free(myUIDs);
myUIDs=ss;
free(buffer);
}
}
答案 0 :(得分:3)
我在进一步审核中看到了几个问题...
简而言之,您获得的错误似乎不是您正在执行的行的结果,而是先前内存损坏的副作用。
您在哪里初始化myUIDs
?如果没有根据提供的代码定义
您正在从fname
分配pData
,这是指向动态分配的buffer
的指针...您随后会在下一行执行时释放,这意味着fname
现在指向已释放的内存。然而,你试图在后面的代码中读取它...这可能会引导你随意浏览内存。
代码中有多个实例,您动态分配内存,然后尝试使用它而不验证您实际获得了所请求的分配。
您根据malloc()
的返回值调用snprintf()
,但未确认snprintf()
是否为您返回了非负值。虽然,我怀疑这是一个问题,但这是不明智的。
可以肯定的是,您描述的症状是堆损坏的结果。问题是在哪里。我强烈建议使用valgrind。
此外,如果可用,请查看asprintf()
而不是您正在进行的malloc( snprintf() )
工作。