Why does this code crash when I declare one more variable? - c

Here's my code. It works when I comment out the "luetut" variable.
But when I compile as follows, I get segmentation fault when the program should print the variables. What sense does this make? When I try to make a debug build, something totally weird shows up (multiple definition of this and that).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct rakenne
{
int luku;
float liukuluku;
char* mjono;
} Rakenne;
int main(int argc, char *argv[])
{
int luetut = 0;
Rakenne palikka;
// Rakenne palikka, *palikkaosoitin;
// palikkaosoitin = &palikka;
// while(luetut < 1)
// {
printf("Anna luku:\n");
scanf("%d", &palikka.luku);
// } luetut = 0;
// while(luetut < 1)
// {
printf("Anna liukuluku:\n");
scanf("%f", &palikka.liukuluku);
// } luetut = 0;
printf("Anna merkkijono:\n");
scanf("%s", palikka.mjono);
printf("%i\t%.3f\t%s\n", palikka.luku, palikka.liukuluku, palikka.mjono);
return 0;
}
So, is my gcc compiler broken or what could be the problem?

scanf("%s", palikka.mjono);
You didn't make mjono point to anything so writing to it is of course illegal - undefined behavior. Doing something like this leads to erratic behavior: the program "works" or "fails" for no apparent reason.
So, is my gcc compiler broken or what could be the problem
It's rarely constructive to think the tools you are using are the problem.

Expanding on cnicutars answer, the fix would be to allocate some memory for palikka.mjono.
Something like this:
#define SIZE 40 // or whatever you need.
palikka.mjono = malloc( sizeof(char) * SIZE );
Then later don't forget to free that memory:
free( palikka.mjono );
Or if you know what the maximum size of your strings will be, just define your structure as:
typedef struct rakenne
{
int luku;
float liukuluku;
char mjono[SIZE];
} Rakenne;

Related

Segmentation fault while function call

I got a struct Chat
struct Chat
{
int m_FD;
int m_BindPort;
char m_NameLength;
char* m_Name;
char m_PeerCount;
char** m_PeerList;
} typedef Chat_t;
i'm initializing it with this function:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen+1));
strcpy(this->m_Name, name);
this->m_BindPort = bindPort;
this->m_PeerCount = peerCount;
this->m_PeerList = malloc(sizeof(char*) * peerCount);
for(int i=0; i<peerCount; i++)
{
this->m_PeerList[i] = malloc(sizeof(char) * 16); // enough for xxx.xxx.xxx.xxx\0
strcpy(this->m_PeerList[i], peerList[i]);
}
//Socket initialization for TCP connection...
//Commenting this out doesn't change anything so i'm hiding it for simplification
return 0;
}
After that i'm calling a second function
int chat_communicate(Chat_t* this)
{
printf("2\n");
fflush(stdout);
//Some stuff that doesn't matter because it isn't even called
return retVar;
}
in main like this
void main(void)
{
char* peerList[1];
char username[USERNAME_MAX_LEN];
int initRet;
int loopRet;
Chat_t chat;
peerList[0] = "192.168.2.2";
memset(username, 0, USERNAME_MAX_LEN);
printf("Please enter your user name: ");
scanf("%s", username);
username[USERNAME_MAX_LEN-1] = 0;
initRet = chat_init(&chat, strlen(username), username, 1234, 1, peerList);
printf("File Descriptor: %d\n", chat.m_FD);
printf("Binding Port: %d\n", chat.m_BindPort);
printf("Name Length: %d\n", chat.m_NameLength);
printf("Name: %s\n", chat.m_Name);
printf("Peer Count: %d\n", chat.m_PeerCount);
for(int i=0; i< chat.m_PeerCount; i++)
{
printf("Peer[%d]: %s\n", i, chat.m_PeerList[i]);
}
printf("1");
ret = chat_communicate(&chat);
//Even more Stuff that isn't even called
}
My program outputs the following
File Descriptor: 3
Binding Port: 1234
Name Length: 4
Name: User
Peer Count: 1
Peer[0]: 192.168.2.2
1
Segmentation Fault
It compiles without errors or even warnings.
You can also assume that every string is null-Terminated The stuff i replaced with comments itn't that complicated but just too much to show.
Every value inside the struct is printed with printf right before but when passing this very struct per reference the application crashes.
What i want to know is why i'm getting this Segmentation Fault. Since it appeared while calling a function i thought it is some kind of layout problem but i havn't find anything like that.
Addition:
Because some people weren't able to believe me that the code i hid behind "some stuff" comments doesn't change anything i want to state this here once again. This code just contains a tcp socket communication and only performs read-operations. I also am able to reproduce the error mentioned above without this code so please don't get stuck with it. Parts does not influence the object under observation at all.
Among other potential problems,
this->m_PeerList = malloc(sizeof(char)*peerCount);
is clearly wrong.
m_PeerList is a char **, yet you're only allocating peerCount bytes, which only works if a char * pointer is one byte on your system - not likely.
Replace it with something like
this->m_PeerList = malloc(peerCount * sizeof( *( this->m_peerList ) ) );
Note that sizeof( char ) is always one - by definition.
You're not allocating enough memory for the this->m_Name. It should be on more than this if you want it to store the null-terminated string of the name.
That, or we need more information about the peerList.
Now that you have posted an almost complete code, I was able to spot two problems next to each other:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen + 1)); // correct
//< this->m_Name = malloc(sizeof(char) * nameLen); // wrong
strcpy(this->m_Name, name); // correct
//< memcpy(this->m_Name, name, nameLen); // wrong
...
The lines starting with //< is your original code:
Here you don't allocate enough space, you need to account for the NUL terminator:
this->m_Name = malloc(sizeof(char) * nameLen);
And here you don't copy the NUL terminator:
memcpy(this->m_Name, name, nameLen);
You really need to be aware how strings work in C.
Why don't you debug it yourself. If using GCC, compile your code with options -g -O0. Then run it with gdb:
gdb ./a.out
...
(gdb) r
If it crashes do:
(gdb) bt
This will give exactly where it crashes.
Update: There may be potential problems with your code as found by other users. However, memory allocation related issues will not crash your application just on calling function chat_communicate. There could be different reasons for this behaviour ranging from stack overflow to improper compilation. Without seeing the whole code it is very difficult to tell. Best advice is to consider review comments by other users and debug it yourself.

How to use the array from another function in main?

Edit: I made some changes at my code.
I want to write a line fitting program by using the data from two .txt file. The code is as following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int data_read(char programs_x[], char programs_y[]) {
int i=0, j=0, k;
int numProgs_x=0;
int numProgs_y=0;
char line_x[1024];
char line_y[1024];
FILE *file_x;
FILE *file_y;
file_x = fopen("data_x.txt", "r");
file_y = fopen("data_y.txt", "r");
while(fgets(line_x, sizeof line_x, file_x)!=NULL) {
//check to be sure reading correctly
//printf("%s", line_x);
//add each filename into array of programs
programs_x[i]=strdup(line_x);
i++;
//count number of programs in file
numProgs_x++;
}
while(fgets(line_y, sizeof line_y, file_y)!=NULL) {
//check to be sure reading correctly
//printf("%s", line_y);
//add each filename into array of programs
programs_y[j]=strdup(line_y);
j++;
//count number of programs in file
numProgs_y++;
}
fclose(file_x);
fclose(file_y);
return 0;
}
int main ( void ) {
int i, j, k, n=1024;
float s1=0,s2=0,s3=0,s4=0,a,d,b;
char programs_x[1024], programs_y[1024];
data_read(programs_x, programs_y);
for(i=0;i<n;i++) {
scanf("%f", &programs_x[k]);
}
for(i=0; i<n; i++){
scanf("%f", &programs_y[k]);
}
for(i=0;i<n;i++) {
s1=s1+programs_x[i];
s2=s2+programs_x[i] * programs_x[i];
s3=s3+programs_y[i];
s4=s4+programs_x[i] * programs_y[i];
}
d=n*s2-s1*s1;
a=(s2*s3-s1*s4)/d;
b=(n*s4-s1*s3)/d;
printf("\nThe values of a and b are : %f\t%f\n",a,b);
printf("\nThe Required Linear Relation is : \n");
if(b>0){
printf("\ny=%f+%fx\n",a,b);
}
else {
printf("y=%f%fx",a,b);
}
return 0;
}
When I try to compile this code, the compiler shows these error:
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
test3.c:
Error E2349 test3.c 22: Nonportable pointer conversion in function data_read
Error E2349 test3.c 33: Nonportable pointer conversion in function data_read
*** 2 errors in Compile ***
How do I fix the errors? Where did I make mistakes in declaring and calling the data types? I'm pretty sure I declare programs_x and programs_y as char this time and not int.
The error is difficulty to pin down as we don't have line numbers but this line is definitely not right in your main:
data_read(char programs_x[], char programs_y[]);
To call a function you just list the variables and values you're passing to it like this:
data_read(programs_x, programs_y);
Which will no doubt cause more errors/warnings to be flagged as you declare programs_x and programs_y as arrays of int, but data_read is expecting arrays of char. So there's a conflict in what you think your function wants and what you're providing to it which you need to sort out.
The error could mean that the non-standard function strdup() is not supported. A C compiler does not need to support it, which is why it is a good idea to avoid that function. If the function is supported as a non-standard extension (it is part of POSIX), you might find it in the header <string.h> which you didn't include.
As for the cause of the rest of the errors, I have no idea, since those appear to originate from other files than the one you posted.

Segfault thrown on one line of code

I am using this library for libgps and having a few issues with it getting it to run properly.
The error from my debugger after it says segfault is:
Cannot find bounds of current function
The line of code throwing this is located in this file, on line 132.
uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16);
I don't know the context of this at all, and I dont know why it would / wouldn't throw a segfault.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <gps.h>
#include <math.h>
/*
*
*/
int main(int argc, char** argv) {
// Open
gps_init();
gps_on();
loc_t data;
gps_location(&data);
printf("%lf %lf\n", data.latitude, data.longitude);
return (EXIT_SUCCESS);
}
The function gps_location() takes you into gps.c and from there it runs into serial.c, once it runs:
void serial_readln(char *buffer, int len)
{
char c;
char *b = buffer;
int rx_length = -1;
while(1) {
rx_length = read(uart0_filestream, (void*)(&c), 1);
if (rx_length <= 0) {
//wait for messages
sleep(1);
} else {
if (c == '\n') {
*b++ = '\0';
break;
}
*b++ = c;
}
}
}
On the break it returns to gps.c goes into:
switch (nmea_get_message_type(buffer)) {
which takes it into nmea.c for nmea_get_message_type above.
It then runs the line:
if ((checksum = nmea_valid_checksum(message)) != _EMPTY)
taking it down to: uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16); which is where the error is.
What is causing this?
Edit:
uint8_t is defined as: typedef unsigned char uint8_t;
Segmentation fault is not a "thrown exception" per se, it is a hardware-issued problem ("you said go there, but I don't see anything named 'there'").
As for your problem: what happens when strchr() does not find the specified character? I suggest you try it and find out.
The code you are working with is horrible and has no error checking anywhere. So it may go haywire for any unexpected input. This could be a potential security vulnerability too.
To fix this particular instance, change the code to:
if ( !message )
return NMEA_CHECKSUM_ERR; // possibly `exit` or something, this shouldn't happen
char *star = strchr(message, '*');
if ( !star )
return NMEA_CHECKSUM_ERR;
uint8_t checksum = strtol(star, NULL, 16);
The nmea_parse_gpgga and nmea_parse_gprmc also have multiple instances of a similar problem.
These functions might be acceptable if there was a parser or a regexp check that sanitizes the input before calling these functions. However, based on your question (I didn't check the codebase), it seems data is passed directly from read which is inexcusable.
The segfaulting function was not designed to handle an empty message or in fact any message not matching the expected form.
Another disastrous blunder is that the serial_readln function never checks that it does not write beyond len.

Bad memory access while calling function

Actually i developing using unit test.
But i break down my code in other form to ask for the error that i faced.
I have these declaration in my header file
typedef struct
{
void *topOfStack;
}Stack;
typedef enum {NUMBER,OPERATOR,IDENTIFIER}Token;
int operatorEvaluate(Stack *numberStack , Stack *operatorStack);
void * pop(Stack *stack);
The following is the respective source file
#include "try.h"
void *pop(Stack *numberStack)
{
Token *newToken = NUMBER;
return newToken;
}
int operatorEvaluate(Stack *numberStack , Stack *operatorStack)
{
Token *first = (Token*)pop (numberStack);
if(numberStack != operatorStack)
{
if(*first == NUMBER)
return 1;
}
return 0;
}
This is the source file that i call the functions which is main
#include "try.h"
#include <stdio.h>
int main ()
{
Stack numberStack;
Stack operatorStack;
int num;
num = operatorEvaluate(&numberStack , &operatorStack);
printf("This is the returned value: %d",num);
return 0;
}
When i tried to compile, the unit test tell me that bad memory access.
So i try to use eclipse to compile these, and windows tells that the .exe had stop working.
Hope someone can help me, i stuck for a long time...
Enable compiler warnings.
In particular, this makes zero sense:
Token *newToken = NUMBER;
That's a pointer, and you're assigning a value.
I cannot propose a fix, as I have no idea what you're doing.
That pop() function isn't touching the stack, and is returning an enum converted to a pointer. If you try to access anything through that pointer, it's going to provoke undefined behavior.
Your pop function is wrong in a few ways. You probably want it to actually pop your stack, rather than return a constant (which it isn't doing either, by the way!)...something like this:
void *pop(Stack *numberStack)
{
return numberStack->topOfStack;
}
but if you do that it'll still crash, because you never initialize your stack OR fill the topOfStack pointer.

Why am I getting a "Segmentation Fault" error when I try to run the tests?

I've written a function that determines whether or not to assign default values (it assigns default values if the flag is not present, and it assigns values the user passes if the flag is present). And I'm trying to test my function with a string to see if it did give me the right numbers. I keep getting "Segmentation Fault" when I try to run the tests, it compiles, but the tests just don't work. :(
Here's my header file:
#ifndef COMMANDLINE_H
#define COMMANDLINE_H
#include "data.h"
#include <stdio.h>
struct point eye;
/* The variable listed above is a global variable */
void eye_flag(int arg_list, char *array[]);
#endif
Here's my implementation file:
#include <stdio.h>
#include "commandline.h"
#include "data.h"
#include "string.h"
/* Used global variables for struct point eye */
void eye_flag(int arg_list, char *array[])
{
eye.x = 0.0;
eye.y = 0.0;
eye.z = -14.0;
/* The values listed above for struct point eye are the default values. */
for (int i = 0; i <= arg_list; i++)
{
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
}
And here are my test cases:
#include "commandline.h"
#include "checkit.h"
#include <stdio.h>
void eye_tests(void)
{
char *arg_eye[6] = {"a.out", "sphere.in.txt", "-eye", "2.4", "3.5", "6.7"};
eye_flag(6, arg_eye);
checkit_double(eye.x, 2.4);
checkit_double(eye.y, 3.5);
checkit_double(eye.z, 6.7);
char *arg_eye2[2] = {"a.out", "sphere.in.txt"};
eye_flag(2, arg_eye2);
checkit_double(eye.x, 0.0);
checkit_double(eye.y, 0.0);
checkit_double(eye.z, -14.0);
}
int main()
{
eye_tests();
return 0;
}
The absolute easiest way to solve this one is run it in a debugger. You probably won't even need to learn how to step through your code or anything - just fire up, run, and read the line.
If you are on a *nix system:
Compile your code with -g flag.
Load as, e.g. gdb a.out.
Run now that it's loaded - (gdb) run.
Do whatever you need to reproduce the segfault.
bt or where should give you a stack trace - and an exact line that is causing your problem.
I'm sure enough you can solve it from there to post this as an answer; but if not, knowing the exact line will make it very much easier to research and solve.
The errors are here:
for (int i = 0; i <= arg_list; i++)
{ ///^^
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
//^^^
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
i <= arg_list is wrong since you pass in 6, array index starts from 0, the max value is 5
i+1, i+2,i+3 will give you out of bounds index when you iterate from 0 to 5.
Your loop condition is wrong. It should be i < arg_list.
Think about what happens when i == arg_list.

Resources