473,287 Members | 1,560 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,287 software developers and data experts.

Segmentation fault with array

Hi, I'm getting confused with arrays and hope someone can shed light
on my code.
I wrote this to try and learn about files and arrays as I thought if I
could grab each element and place them into an array I can manipulate
the stings from the file with array indexes.
Perhaps there's a better method but I'm learning.

#include <stdio.h>
#include <stdlib.h>

int main()
{
char c;
int num=0;
int count=0;
int i;
char instring[10];

FILE * fp;

if((fp=fopen("testdata.txt","r"))==NULL)
{
printf("Error in openning the file.\n");
exit(2);
}

while(!feof(fp))
{
num++;
if ((c = getc(fp))==EOF)
{
printf("EOF reached \n");
break;
}
else
{
if (c != '\0')
{
instring[count] =c;
printf("count = %d, instring = %c\n",count,instring[count]);
count++;
}
}
}

i=0;
printf("char 3 is %c\n",instring[i+3]);

return 0;
}

The testdata.txt contains
ab$
e.f
1we
@\/
"@'
:]_
..

When I execute the program I get the following result:
count = 0, instring = a
count = 1, instring = b
count = 2, instring = $
count = 3, instring =

count = 4, instring = e
count = 5, instring = .
count = 6, instring = f
count = 7, instring =

count = 8, instring = 1
count = 9, instring = w
count = 10, instring = e
count = 11, instring =

count = 12, instring = @
count = 13, instring = \
count = 14, instring = /
count = 15, instring =

count = 16, instring = "
count = 17, instring = @
count = 18, instring = '
count = 19, instring =

Segmentation Fault (core dumped)

My question is if the instring has 10 elements then why is it printing
out to element 19 ?
If I put a large number, such as char instring[150], then it will work

Have I misunderstood arrays completely ?

Pat

May 19 '07 #1
14 2781
pt*****@gmail.com wrote:
Hi, I'm getting confused with arrays and hope someone can shed light
on my code.
I wrote this to try and learn about files and arrays as I thought if I
could grab each element and place them into an array I can manipulate
the stings from the file with array indexes.
Perhaps there's a better method but I'm learning.

#include <stdio.h>
#include <stdlib.h>

int main()
{
char c;
int num=0;
int count=0;
int i;
char instring[10];

FILE * fp;

if((fp=fopen("testdata.txt","r"))==NULL)
{
printf("Error in openning the file.\n");
exit(2);
}

while(!feof(fp))
{
num++;
if ((c = getc(fp))==EOF)
{
printf("EOF reached \n");
break;
}
else
{
if (c != '\0')
{
instring[count] =c;
printf("count = %d, instring = %c\n",count,instring[count]);
count++;
}
}
}

i=0;
printf("char 3 is %c\n",instring[i+3]);

return 0;
}
My question is if the instring has 10 elements then why is it printing
out to element 19 ?
If I put a large number, such as char instring[150], then it will work

Have I misunderstood arrays completely ?
You have an array of single characters, which you then fill, and keep
writing to without checking if you have written past the end. It looks
like you intended to read lines, rather than single characters.

--
Ian Collins.
May 19 '07 #2
Ian answered your actual question, so let me point out another problem
in your code:
char c;
....
if ((c = getc(fp))==EOF)
The function getc returns an integer. I know, that's crazy, but
that's the way it is. (Not all standard library functions have good
interfaces.) The comparison to EOF can fail (I forget whether it
always does or only does on certain implementations) if c is a
character instead of an int.

Michael

May 19 '07 #3
Michael wrote:
Ian answered your actual question, so let me point out another problem
in your code:
> char c;
...
> if ((c = getc(fp))==EOF)

The function getc returns an integer. I know, that's crazy, but
that's the way it is.
Suppose `getc` returned a `char`. What `char` value would you
pick to represent EOF and hence disallow from appearing in any
FILE* input?

Remember that FILE*s can be reading "binary" files.

--
Three-Way Secret Hedgehog
A rock is not a fact. A rock is a rock.

May 19 '07 #4
pt*****@gmail.com wrote:
Hi, I'm getting confused with arrays and hope someone can shed light
on my code.
I wrote this to try and learn about files and arrays as I thought if I
could grab each element and place them into an array I can manipulate
the stings from the file with array indexes.
Perhaps there's a better method but I'm learning.

#include <stdio.h>
#include <stdlib.h>

int main()
{
char c;
int num=0;
int count=0;
int i;
char instring[10];

FILE * fp;

if((fp=fopen("testdata.txt","r"))==NULL)
{
printf("Error in openning the file.\n");
exit(2);
}

while(!feof(fp))
{
num++;
if ((c = getc(fp))==EOF)
{
printf("EOF reached \n");
break;
}
else
{
if (c != '\0')
{
instring[count] =c;
printf("count = %d, instring = %c\n",count,instring[count]);
count++;
}
}
}

i=0;
printf("char 3 is %c\n",instring[i+3]);

return 0;
}

The testdata.txt contains
ab$
e.f
1we
@\/
"@'
:]_
.

When I execute the program I get the following result:
count = 0, instring = a
count = 1, instring = b
count = 2, instring = $
count = 3, instring =

count = 4, instring = e
count = 5, instring = .
count = 6, instring = f
count = 7, instring =

count = 8, instring = 1
count = 9, instring = w
count = 10, instring = e
count = 11, instring =

count = 12, instring = @
count = 13, instring = \
count = 14, instring = /
count = 15, instring =

count = 16, instring = "
count = 17, instring = @
count = 18, instring = '
count = 19, instring =

Segmentation Fault (core dumped)

My question is if the instring has 10 elements then why is it printing
out to element 19 ?
If I put a large number, such as char instring[150], then it will work

Have I misunderstood arrays completely ?
What you seem to be missing is that in C it is *your* responsibility, as
a programmer, to ensure that you will not go outside the array bounds.
The compiler is not required (and sometimes even not able) to check that
you stay within array bounds.

In your code, you were happily clobbering over some random memory, until
the processor determined that something was seriously wrong. This is
perfectly acceptable behaviour if the programmer forgets his/her duty
to check array bounds. (By accessing memory outside the array bounds,
you invoke undefined behaviour. Anything the computer does then is
fully correct.)
>
Pat
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
May 19 '07 #5
On 18 May 2007 22:28:50 -0700, pt*****@gmail.com wrote:
>Hi, I'm getting confused with arrays and hope someone can shed light
on my code.
I wrote this to try and learn about files and arrays as I thought if I
could grab each element and place them into an array I can manipulate
the stings from the file with array indexes.
Perhaps there's a better method but I'm learning.

#include <stdio.h>
#include <stdlib.h>

int main()
{
char c;
The return value from getc needs to be an int, not a char.
int num=0;
int count=0;
int i;
char instring[10];

FILE * fp;

if((fp=fopen("testdata.txt","r"))==NULL)
{
printf("Error in openning the file.\n");
exit(2);
2 is not a portable return value from main. Use EXIT_FAILURE which is
a macro that each system defines consistent with your environment.
}

while(!feof(fp))
Since you test for EOF inside the loop, calling the function here is
superfluous.
{
num++;
if ((c = getc(fp))==EOF)
It is not guaranteed that the char c can hold the value EOF. It needs
to be an int.
{
printf("EOF reached \n");
break;
}
else
{
if (c != '\0')
In a text file, it is unlikely that c will ever equal '\0''\.
{
instring[count] =c;
printf("count = %d, instring = %c\n",count,instring[count]);
The fact that c was not equal to EOF or '\0' does not mean it is a
printable character. It could have been '\n' indicating end of line
(not end of file) or other common text markers such as '\t'.
count++;
}
}
}
The most likely cause of your segmentation faults is not insuring that
count never exceeds 9. Once it does and you attempt to store or print
instring[10], you have exceeded the array bounds and invoked undefined
behavior.
>
i=0;
printf("char 3 is %c\n",instring[i+3]);

return 0;
}

The testdata.txt contains
ab$
e.f
1we
@\/
"@'
:]_
.

When I execute the program I get the following result:
count = 0, instring = a
count = 1, instring = b
count = 2, instring = $
count = 3, instring =
This is what happens when you attempt to printf a '\n' with %c.
>count = 4, instring = e
count = 5, instring = .
count = 6, instring = f
count = 7, instring =

count = 8, instring = 1
count = 9, instring = w
count = 10, instring = e
Of course this element does not exist and everything from this point
on is undefined behavior.
>count = 11, instring =

count = 12, instring = @
count = 13, instring = \
count = 14, instring = /
count = 15, instring =

count = 16, instring = "
count = 17, instring = @
count = 18, instring = '
count = 19, instring =

Segmentation Fault (core dumped)

My question is if the instring has 10 elements then why is it printing
out to element 19 ?
Because the c language does not require bounds checking during
run-time. It was a design decision by the language developers to
leave this task to the programmer. Since you didn't, you experienced
to different possible manifestations of undefined behavior. The first
ten times it did something "almost reasonable". The next time it did
something so unreasonable your operating system had to intercede and
terminate your program.
>If I put a large number, such as char instring[150], then it will work
It will work longer but if your file has more than 150 characters you
will end up with the same problem. What you really need to do is add
code to your while loop to check the value of count and do something
special (terminate with a warning message, reset count back to 0, etc)
when it exceeds the size of instring.
>
Have I misunderstood arrays completely ?
What did you expect to happen when you exceeded the array size?
Remove del for email
May 19 '07 #6
pt*****@gmail.com wrote:
>
Hi, I'm getting confused with arrays and hope someone can shed
light on my code.
I wrote this to try and learn about files and arrays as I thought
if I could grab each element and place them into an array I can
manipulate the stings from the file with array indexes.
Perhaps there's a better method but I'm learning.

#include <stdio.h>
#include <stdlib.h>

int main(void) { /* added void for clarity */
char c;
int num=0;
int count=0;
int i;
char instring[10];
FILE * fp;

if ((fp = fopen("testdata.txt","r")) == NULL) {
printf("Error in openning the file.\n");
exit(EXIT_FAILURE); /* note change here **/
}
while (!feof(fp) && count < 10 ) { /* note change here **/
num++;
if ((c = getc(fp)) == EOF) {
printf("EOF reached \n");
break;
}
else {
if (c != '\0') {
instring[count] = c;
printf("count = %d, instring = %c\n",
count, instring[count]); /* clarity
edit */
count++;
}
}
}
i = 0;
printf("char 3 is %c\n", instring[i + 3]);
return 0;
}
I have edited your code slightly to reduce the vertical space.
Note the added comments. Search for '**/'. It is up to you to
ensure you do not write on unowned memory.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

May 20 '07 #7
On May 19, 12:23 am, Chris Dollin <e...@electrichedgehog.netwrote:
Michael wrote:
Ian answered your actual question, so let me point out another problem
in your code:
char c;
...
if ((c = getc(fp))==EOF)
The function getc returns an integer. I know, that's crazy, but
that's the way it is.

Suppose `getc` returned a `char`. What `char` value would you
pick to represent EOF and hence disallow from appearing in any
FILE* input?

Remember that FILE*s can be reading "binary" files.

--
Alternately, suppose you wrote a function where the description is
"read the next thing and return an int, not a char." Would you call
such a function getc?

Or suppose your description of your function was: sometimes return one
thing, sometimes return another (e.g., return a char except if you
don't, because you've reached end of file, or if an error occurs).
Would you think that, perhaps, a better interface was in order?

Or suppose you developed an interface that was commonly misused, and
in fact, was incredibly easy to misuse, because you had a combination
of: 1) outputs that mean different things, 2) a bad name, and 3) a
common misuse pattern that can not be caught by the compiler. If you
were the one to develop such an interface, I would blame you, not the
poor schmucks who were confused by your inanity. Although I suppose
that the typical thing is design such goofiness, document it, and them
blame the person who uses the interface for not reading the
documentation closely enough, regardless of how poorly the interface
is designed.

</rant>

Michael
May 20 '07 #8
Thank you for everyone's reply.
I've followed through with the suggestions and it's now working.
I think I would be better off by drawing up a diagram of my logic
first next time.

May 20 '07 #9
On May 19, 10:43 am, Ian Collins <ian-n...@hotmail.comwrote:
ptq2...@gmail.com wrote:
Hi, I'm getting confused with arrays and hope someone can shed light
on my code.
I wrote this to try and learn about files and arrays as I thought if I
could grab each element and place them into an array I can manipulate
the stings from the file with array indexes.
Perhaps there's a better method but I'm learning.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
int num=0;
int count=0;
int i;
char instring[10];
FILE * fp;
if((fp=fopen("testdata.txt","r"))==NULL)
{
printf("Error in openning the file.\n");
exit(2);
}
while(!feof(fp))
{
num++;
if ((c = getc(fp))==EOF)
{
printf("EOF reached \n");
break;
}
else
{
if (c != '\0')
{
instring[count] =c;
printf("count = %d, instring = %c\n",count,instring[count]);
count++;
}
}
}
i=0;
printf("char 3 is %c\n",instring[i+3]);
return 0;
}
My question is if the instring has 10 elements then why is it printing
out to element 19 ?
If I put a large number, such as char instring[150], then it will work
Have I misunderstood arrays completely ?

You have an array of single characters, which you then fill, and keep
writing to without checking if you have written past the end. It looks
like you intended to read lines, rather than single characters.

--
Ian Collins.
HAI EVERYBODY. I AM NEW TO C. EVERYBODY ANSWERED TO QUESTION, BUT
NOBODY IS POINTING WHY HE/SHE HAS CHECKED FOR EOF TWICE IN THE
PROGRAM. IS IT NECESSARY????

May 20 '07 #10

"Michael" <mc******@aol.comha scritto nel messaggio
news:11**********************@w5g2000hsg.googlegro ups.com...
On May 19, 12:23 am, Chris Dollin <e...@electrichedgehog.netwrote:
>Michael wrote:
Ian answered your actual question, so let me point out another problem
in your code:
> char c;
...
if ((c = getc(fp))==EOF)
The function getc returns an integer. I know, that's crazy, but
that's the way it is.

Suppose `getc` returned a `char`. What `char` value would you
pick to represent EOF and hence disallow from appearing in any
FILE* input?

Remember that FILE*s can be reading "binary" files.

--

Alternately, suppose you wrote a function where the description is
"read the next thing and return an int, not a char." Would you call
such a function getc?
If you want to use fscanf(fp, "%c", &c) or fread(&c, 1, 1, fp) you
are free to use them. If you would like a function returning a
char, there would be no way to report EOF, unless it looked like
extern unsigned char get(FILE * restrict stream, int *flag), which
IMO is no improvement. So what's your point?
May 20 '07 #11

"Barry Schwarz" <sc******@doezl.netha scritto nel messaggio
news:mc********************************@4ax.com...
On 18 May 2007 22:28:50 -0700, pt*****@gmail.com wrote:
>>When I execute the program I get the following result:
count = 0, instring = a
count = 1, instring = b
count = 2, instring = $
count = 3, instring =

This is what happens when you attempt to printf a '\n' with %c.
What do you mean? printf("%c", '\n') is perfectly valid and does
exactly what it is supposed to do, as shown above.
May 20 '07 #12

<gu*******@gmail.comha scritto nel messaggio
news:11**********************@u30g2000hsc.googlegr oups.com...
On May 19, 10:43 am, Ian Collins <ian-n...@hotmail.comwrote:
>ptq2...@gmail.com wrote:
Hi, I'm getting confused with arrays and hope someone can shed light
on my code.
I wrote this to try and learn about files and arrays as I thought if I
could grab each element and place them into an array I can manipulate
the stings from the file with array indexes.
Perhaps there's a better method but I'm learning.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
int num=0;
int count=0;
int i;
char instring[10];
FILE * fp;
if((fp=fopen("testdata.txt","r"))==NULL)
{
printf("Error in openning the file.\n");
exit(2);
}
while(!feof(fp))
{
num++;
if ((c = getc(fp))==EOF)
{
printf("EOF reached \n");
break;
}
else
{
if (c != '\0')
{
instring[count] =c;
printf("count = %d, instring = %c\n",count,instring[count]);
count++;
}
}
}
i=0;
printf("char 3 is %c\n",instring[i+3]);
return 0;
}
My question is if the instring has 10 elements then why is it printing
out to element 19 ?
If I put a large number, such as char instring[150], then it will work
Have I misunderstood arrays completely ?

You have an array of single characters, which you then fill, and keep
writing to without checking if you have written past the end. It looks
like you intended to read lines, rather than single characters.

--
Ian Collins.

HAI EVERYBODY. I AM NEW TO C. EVERYBODY ANSWERED TO QUESTION, BUT
NOBODY IS POINTING WHY HE/SHE HAS CHECKED FOR EOF TWICE IN THE
PROGRAM. IS IT NECESSARY????
No, it isn't.
They did that because the OP's code did that.
May 20 '07 #13
Michael wrote:
On May 19, 12:23 am, Chris Dollin <e...@electrichedgehog.netwrote:
>Michael wrote:
Ian answered your actual question, so let me point out another problem
in your code:
> char c;
...
if ((c = getc(fp))==EOF)
The function getc returns an integer. I know, that's crazy, but
that's the way it is.

Suppose `getc` returned a `char`. What `char` value would you
pick to represent EOF and hence disallow from appearing in any
FILE* input?

Remember that FILE*s can be reading "binary" files.

Alternately, suppose you wrote a function where the description is
"read the next thing and return an int, not a char." Would you call
such a function getc?
(a) No. But `getc` doesn't return "an int". It returns the int value
of a char or EOF. Typically it returns a `char`. I'd call it
`getChar`, and consider giving it return type CharOrEOF, or
Optional(char), or char??, depending on the language I was
writing this function in, and its observed conventions.

(b) I note you didn't answer my question. Either reach-the-next
char returns a char, and so can't signal EOF in its return value,
or it returns a non-char, and so can't signal the type of
the interesting value it returns. Perfection is a vice.
Or suppose your description of your function was: sometimes return one
thing, sometimes return another (e.g., return a char except if you
don't, because you've reached end of file, or if an error occurs).
Would you think that, perhaps, a better interface was in order?
I'd think a better /description/ was in order. Or a better programming
language.
Or suppose you developed an interface that was commonly misused, and
in fact, was incredibly easy to misuse, because you had a combination
of: 1) outputs that mean different things, 2) a bad name, and 3) a
common misuse pattern that can not be caught by the compiler. If you
were the one to develop such an interface, I would blame you, not the
poor schmucks who were confused by your inanity. Although I suppose
that the typical thing is design such goofiness, document it, and them
blame the person who uses the interface for not reading the
documentation closely enough, regardless of how poorly the interface
is designed.
Were there more room for manoeuver in the existing code, yes. There
isn't. It's a shame, but there it is.
</rant>
Oh no! The ENTIRE STACK of commentary is unwinding! Gibble ... umph ...

!gnidniwun si yratnemmoc fo KCATS ERITNE htT !on hO

(fx:snip)

--
Far-Fetched Hedgehog
The shortcuts are all full of people using them.

May 20 '07 #14
On Sun, 20 May 2007 18:45:18 +0200, "Army1987" <pl********@for.it>
wrote:
>
"Barry Schwarz" <sc******@doezl.netha scritto nel messaggio
news:mc********************************@4ax.com.. .
>On 18 May 2007 22:28:50 -0700, pt*****@gmail.com wrote:
>>>When I execute the program I get the following result:
count = 0, instring = a
count = 1, instring = b
count = 2, instring = $
count = 3, instring =

This is what happens when you attempt to printf a '\n' with %c.

What do you mean? printf("%c", '\n') is perfectly valid and does
exactly what it is supposed to do, as shown above.
Of course it is.

Since the OP asked why his output was strange without specifying what
he found strange other than the segfault, I annotated everything I
thought a newcomer would be puzzled by.
Remove del for email
May 20 '07 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Vishal Grover | last post by:
Hello Everyone, I am seeing a certain behaviour which I find strange, and am curious to get an explanation to it. I have the following program. #include <iostream> #include <cstdlib> using...
3
by: diyanat | last post by:
i am writing a cgi script in C using the CGIC library, the script fails to run, i am using apache on linux error report from apache : internal server error Premature end of script headers:...
3
by: Zheng Da | last post by:
Program received signal SIGSEGV, Segmentation fault. 0x40093343 in _int_malloc () from /lib/tls/libc.so.6 (gdb) bt #0 0x40093343 in _int_malloc () from /lib/tls/libc.so.6 #1 0x40094c54 in malloc...
18
by: Digital Puer | last post by:
Hi, I'm coming over from Java to C++, so please bear with me. In C++, is there a way for me to use exceptions to catch segmentation faults (e.g. when I access a location off the end of an array)?...
19
by: Sameer | last post by:
Hi friends, I am using Mandriva Linux 9.2 and gcc. My source code is, int chunkin ; //no error int i ; for (i=0;i<7225;i++) { chunkin = somedata ;
59
by: Christian Christmann | last post by:
Hi, I'm wondering why this program does not crash with a segmentation fault: #include <malloc.h> #include <string.h> #include <stdio.h> int main()
27
by: lovecreatesbea... | last post by:
This code snippet is an exercise on allocating two dimension array dynamically. Though this one is trivial, is it a correct one? Furthermore, when I tried to make these changes to the original...
6
by: DanielJohnson | last post by:
int main() { printf("\n Hello World"); main; return 0; } This program terminate just after one loop while the second program goes on infinitely untill segmentation fault (core dumped) on...
6
drumgirl67
by: drumgirl67 | last post by:
I am getting a segmentation fault in a function in a C++ program. "fields" is a two dimensional array that was passed to the function. Each "row" in fields is a 32 character array, and the total...
3
by: jr.freester | last post by:
I have created to classes Matrix and System. System is made up of type matrix. ---------------------------------------------------------------------------------- class Matrix { private: int...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.