C 分段故障总是在3次输入后发生
我有以下代码来接受用户的任意行数,并打印出长度>80个字符的行数:-C 分段故障总是在3次输入后发生,c,segmentation-fault,C,Segmentation Fault,我有以下代码来接受用户的任意行数,并打印出长度>80个字符的行数:- #include <stdio.h> #include <stdlib.h> #include "shared.h" #include <string.h> int MAXLINE = 10; int INCREMENT = 10; int NUM = 1; char* longest = NULL; char* line = NULL; char** row = NULL; voi
#include <stdio.h>
#include <stdlib.h>
#include "shared.h"
#include <string.h>
int MAXLINE = 10;
int INCREMENT = 10;
int NUM = 1;
char* longest = NULL;
char* line = NULL;
char** row = NULL;
void _memcleanup(){
int i =0;
free(line);
free(longest);
for(i=0;i<NUM;i++){
free(row[i]);
}
free(row);
}
void print_lines(int len){
int i;
for(i=0;i<len;i++){
if(strlen(row[i])>80){
printf("%s\n",row[i]);
}
}
}
void copy(char** longest, char** line){
int i=0;
char* temp = realloc(*longest,(MAXLINE)*sizeof(char));
if(temp == NULL){
printf("%s","Unable to allocate memory");
_memcleanup();
exit(1);
}
*longest = temp;
while(((*longest)[i] = (*line)[i]) != '\0'){
++i;
}
longest[i] = '\0';
}
void store(char** s, int pos){
int i=0;
char* temp = realloc(row[pos],(MAXLINE)*sizeof(char));
if(temp == NULL){
printf("%s","Unable to allocate memory");
_memcleanup();
exit(1);
}
row[pos] = temp;
while((row[pos][i] = (*s)[i]) != '\0'){
++i;
}
row[pos][i] = '\0';
}
int _getline(char** s, int pos){
int i,c;
for(i=0; ((c=getchar())!=EOF && c!='\n'); i++){
if(i == MAXLINE - 2){
char* temp = realloc(*s,(MAXLINE + INCREMENT)*sizeof(char));
if(temp == NULL){
printf("%s","Unable to allocate memory");
_memcleanup();
exit(1);
}
*s= temp;
MAXLINE += INCREMENT;
}
(*s)[i] = c;
}
if(c == '\n'){
(*s)[i++] = c;
}
(*s)[i]= '\0';
store(s, pos);
return i;
}
int main(){
int max=0, len, i=0;
line = malloc(MAXLINE*sizeof(char));
longest = malloc(MAXLINE*sizeof(char));
//array of character pointers
row = malloc(NUM*sizeof(char*));
//allocate memory for each row in the array
for(i = 0; i < NUM; i++){
row[i]= malloc(MAXLINE*(sizeof(char)));
}
i=0;
//for(i=0; len = _getline(&line)) > 0; i++){
while((len = _getline(&line, i)) > 0){
printf("%d %d", len, MAXLINE);
/* if(len > max){ */
/* max = len; */
/* copy(&longest, &line); */
/* } */
i++;
}
/* if(max>0){ */
/* printf("%s",longest); */
/* } */
print_lines(i);
_memcleanup();
return 0;
}
#包括
#包括
#包括“shared.h”
#包括
int MAXLINE=10;
int增量=10;
int NUM=1;
char*longest=NULL;
char*line=NULL;
字符**行=空;
void _memcleanup(){
int i=0;
自由线;
免费(最长);
for(i=0;i 0;i++){
而((len=_getline(&line,i))>0){
printf(“%d%d”,len,MAXLINE);
/*如果(len>max){*/
/*max=len*/
/*复制(&最长,&行)*/
/* } */
i++;
}
/*如果(max>0){*/
/*printf(“%s”,最长)*/
/* } */
打印行(i);
_memcleanup();
返回0;
}
我遵循的想法是,当行数超过NUM时,重新分配2D数组。现在为了测试它,我将NUM设置为1。然而,即使这样做,程序也很乐意接受多达3个输入,并在程序上下文中的第4个输入(即pos=3)上接受segfaults
为什么它接受3个输入(理想情况下,它本身应该给出一个segfault pos=1,因为我只给出了1的大小,并且我没有为2D阵列分配更多的空间)
工作守则如下:
#include <stdio.h>
#include <stdlib.h>
#include "shared.h"
#include <string.h>
int MAXLINE = 10;
int INCREMENT = 10;
int NUM = 1;
char* longest = NULL;
char* line = NULL;
char** row = NULL;
void _memcleanup(){
int i =0;
free(line);
free(longest);
for(i=0;i<NUM;i++){
free(row[i]);
}
free(row);
}
void print_lines(int len){
int i;
for(i=0;i<len;i++){
if(strlen(row[i])>80){
printf("%s\n",row[i]);
}
}
}
void copy(char** longest, char** line){
int i=0;
char* temp = realloc(*longest,(MAXLINE)*sizeof(char));
if(temp == NULL){
printf("%s","Unable to allocate memory");
_memcleanup();
exit(1);
}
*longest = temp;
while(((*longest)[i] = (*line)[i]) != '\0'){
++i;
}
longest[i] = '\0';
}
void store(char** s, int pos){
int i=0;
if(pos == NUM){
char** temprow = realloc(row, (NUM + INCREMENT)*sizeof(char*));
if(temprow == NULL){
printf("%s","Unable to allocate memory");
_memcleanup();
exit(1);
}
row = temprow;
//allocate space for extra elements
for(i=NUM;i<NUM+INCREMENT;i++){
row[i] = malloc(MAXLINE*sizeof(char));
}
NUM = NUM + INCREMENT;
}
char* temp = realloc(row[pos],(MAXLINE)*sizeof(char));
if(temp == NULL){
printf("%s","Unable to allocate memory");
_memcleanup();
exit(1);
}
row[pos] = temp;
while((row[pos][i] = (*s)[i]) != '\0'){
++i;
}
row[pos][i] = '\0';
}
int _getline(char** s, int pos){
int i,c;
for(i=0; ((c=getchar())!=EOF && c!='\n'); i++){
if(i == MAXLINE - 2){
char* temp = realloc(*s,(MAXLINE + INCREMENT)*sizeof(char));
if(temp == NULL){
printf("%s","Unable to allocate memory");
_memcleanup();
exit(1);
}
*s= temp;
MAXLINE += INCREMENT;
}
(*s)[i] = c;
}
if(c == '\n'){
(*s)[i++] = c;
}
(*s)[i]= '\0';
store(s, pos);
return i;
}
int main(){
int max=0, len, i=0;
line = malloc(MAXLINE*sizeof(char));
longest = malloc(MAXLINE*sizeof(char));
//array of character pointers
row = malloc(NUM*sizeof(char*));
//allocate memory for each row in the array
for(i = 0; i < NUM; i++){
row[i]= malloc(MAXLINE*(sizeof(char)));
}
i=0;
//for(i=0; len = _getline(&line)) > 0; i++){
while((len = _getline(&line, i)) > 0){
printf("%d %d", len, MAXLINE);
/* if(len > max){ */
/* max = len; */
/* copy(&longest, &line); */
/* } */
i++;
}
/* if(max>0){ */
/* printf("%s",longest); */
/* } */
print_lines(i);
_memcleanup();
return 0;
}
#包括
#包括
#包括“shared.h”
#包括
int MAXLINE=10;
int增量=10;
int NUM=1;
char*longest=NULL;
char*line=NULL;
字符**行=空;
void _memcleanup(){
int i=0;
自由线;
免费(最长);
对于(i=0;i=0){
printf(“%d%d”,len,MAXLINE);
/*如果(len>max){*/
/*max=len*/
/*复制(&最长,&行)*/
/* } */
i++;
}
/*如果(max>0){*/
/*printf(“%s”,最长)*/
/* } */
打印行(i);
_memcleanup();
返回0;
}
在main()中,而不是使用
while((len = _getline(&line, i)) > 0){
使用
while(i
对于我来说,更改了代码后,它工作正常。您的问题是:
为什么它接受3个输入(理想情况下,它本身应该给出一个segfault pos=1,因为我只给出了1的大小,并且我没有为2D阵列分配更多的空间)
您是对的,如果您只为一行分配内存,那么如果您尝试访问
行[1],它将调用未定义的行为
。但这种行为只是--未定义的--这意味着你不能依赖程序崩溃。任何事情都可能发生,包括程序似乎工作正常不要给变量所有大写名称;这会使它们看起来像常量。如果我错了,请纠正我,但操作系统不会(在本例中为linux)知道允许程序访问哪些内存位置,从而通过崩溃程序来防止非法访问?我的意思是这不会成为一个安全问题吗?@Karan您在某种程度上是正确的-内核(或者更确切地说,CPU)只能跟踪设置内存范围(又名页面)的权限,很可能是4KB。不可能为每个字节设置权限。此外,允许系统分配比请求的内存更多的内存,但这并不意味着可以安全使用。
while(i< NUM)
{
len = _getline(&line, i);