LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-19-2013, 05:55 AM   #1
shifter
Member
 
Registered: May 2006
Distribution: Slackware, DragonFly
Posts: 233

Rep: Reputation: 30
[C language] segmentation problem with creation of core dump


I'va got a segmentation problem with creation of core dump for the following snippet of c code:

Code:
#include <stdio.h>
#include <string.h>
#include "lezione.h"

studente s1, s2;
studenti s;

int main() {

  int codice;
  char* nome;
  char* cognome;
  int esami;
 

  printf("Leggi uno studente da tastiera e memorizzalo in una struct\n");
  lettura_studente(s1, codice, nome, cognome, esami);

  return 0;

}

void lettura_studente(studente stud, int cod, char n[], char m[], int num) {

  printf("Matricola: ");
  scanf("%d", &cod);
  stud.matricola = cod;

  printf("Nome: ");
  scanf("%s", n);
  strcpy(stud.nome, n);	// Non funziona con stud.nome = n;

  printf("Cognome: ");
  scanf("%s", m);
  strcpy(stud.cognome, m);

  printf("Numero di esami sostenuti: ");
  scanf("%d", &num);
  stud.num_esami = num;

}
In conclusion I'va two problems:
1) Program crash;
2) I can't read struct studente within parameter function.

What are the problems?

Thank you in advance for answers.
 
Old 05-19-2013, 07:01 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
You're application has a bug, that is probably causing it to crash here:
Code:
...
  printf("Nome: ");
  scanf("%s", n);
You should revisit your C book regarding function, and how to pass parameters to such. In your program example, I do not see a need to pass any parameters to the function. After all, you are not using any of them upon returning from the function.

Thus I recommend that you declare your variables local to the function, and avoid global variables. As for the crash, you need to declare space for the name variable 'n'. All you have is an uninitialized pointer that is referencing "somewhere" in memory.

Last edited by dwhitney67; 05-19-2013 at 07:02 AM.
 
Old 05-19-2013, 07:02 AM   #3
H_TeXMeX_H
LQ Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301
You are probably using the wrong operator:

Code:
USE:
stud->matricola
NOT:
stud.matricola
If it's not that, then post the header file as well.
 
Old 05-19-2013, 08:01 AM   #4
shifter
Member
 
Registered: May 2006
Distribution: Slackware, DragonFly
Posts: 233

Original Poster
Rep: Reputation: 30
Code:
You're application has a bug, that is probably causing it to crash here:
Code:

...
  printf("Nome: ");
  scanf("%s", n);
No, the problem is not that because n is just a pointer to array of char.

The problem remains using -> instead .
My header file is the following:
Code:
#define MAX 20

struct record_studente {
  int matricola;
  char* nome;
  char* cognome;
  int num_esami;
};

typedef struct record_studente studente;

typedef studente* studenti;

void lettura_studente(studente, int, char*, char*, int);
void visualizza_studente(studente);
 
Old 05-19-2013, 08:39 AM   #5
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by shifter View Post
No, the problem is not that because n is just a pointer to array of char.
Trust me, it is a problem. You have not reserved any space for the array of char. All you have is a pointer... an uninitialized one at that.

I did not bother to analyze the rest of your code, so undoubtedly there are other errors too (such as reported by TexMex).
 
Old 05-19-2013, 08:47 AM   #6
shifter
Member
 
Registered: May 2006
Distribution: Slackware, DragonFly
Posts: 233

Original Poster
Rep: Reputation: 30
Quote:
Trust me, it is a problem. You have not reserved any space for the array of char. All you have is a pointer... an uninitialized one at that.

I did not bother to analyze the rest of your code, so undoubtedly there are other errors too (such as reported by TexMex).
Yes, my problem is that to copy a string defined as "char*" into another string defined in the same way.

How can I salve this problem?
 
Old 05-19-2013, 10:58 AM   #7
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
With a suitable size for STRING_LENGTH you could try
Code:
struct record_studente {
  int matricola;
  char nome[STRING_LENGTH];
  char cognome[STRING_LENGTH];
  int num_esami;
};
That will reserve space for the strings nome and cognome.
 
Old 05-19-2013, 11:34 AM   #8
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by shifter View Post
How can I salve this problem?
Functions are great for performing the necessary steps of a compartmentalized task. It would seem from the code you have written thus far that the function lettura_studente() is meant merely to capture information about a student within a 'studente' record.
Code:
void lettura_studente(studente, int, char*, char*, int);
The problem with the function above is that you have a declared all parameters as local variables, and these will NOT be visible when the function returns.

Using psionl0 advice, fix your studente structure to pre-allocate memory for the char arrays. Then, all you would need to do is pass the address of a studente object to the function.

For example, in header file:
Code:
#ifndef LEZIONE_H
#define LEZIONE_H

#define MAX_NAME_LENGTH  26    /* arbitrary size */

typedef struct {
  int  matricola;
  char nome[MAX_NAME_LENGTH];
  char cognome[MAX_NAME_LENGTH];
  int  num_esami;
} studente;

void lettura_studente(studente& s);
void visualizza_studente(studente& s);

#endif
For the implementation of lettura_studente(), something as simple as this would suffice:
Code:
int main()
{
    studente s;

    lettura_studente(&s);

    ...

    return 0;
}

void lettura_studente(studente& s)
{
    printf("Matricola: ");
    scanf("%d", &s.matricola);

    printf("Nome: ");
    scanf("%s", s.nome);

    printf("Cognome: ");
    scanf("%s", s.cognome);

    printf("Numero di esami sostenuti: ");
    scanf("%d", &s.num_esami);
}
And, now for deeper advice... never read input from a user using scanf(). Use fgets(), and if a number is needed, then convert it from the string that is inputted. A user is prone to making input errors, sometimes by mistake, other times intentionally.

An example of using fgets()...
Code:
char buffer[80];
int  number = -1;

if (fgets(buffer, sizeof(buffer), stdin) != NULL)
{
    char* newline = strchr(buffer, '\n');    /* check if a newline character is in the buffer */

    if (newline != NULL)
    {
        *newline = '\0';    /* replace the newline with a null-character to mark the end of the string */
    }

    /* to convert input to a number */
    int success = sscanf(buffer, "%d", &number);

    if (success != 1)    /* we are expecting only one conversion */
    {
        fprintf(stderr, "Failed to read number.\n");
    }
}
else
{
    fprintf(stderr, "Failed to read.\n");
}
In the example above, you can substitute 'buffer' with your char array (e.g. nome or cognome) if all you care about is a string. When using sscanf(), substitute 'number' with your variable (e.g. num_esami).
 
Old 05-19-2013, 12:06 PM   #9
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by shifter View Post
Yes, my problem is that to copy a string defined as "char*" into another string defined in the same way.
The biggest problem is that C doesn't really have a "string" data type.

C has many functions and conventions that treat an array of char as if it were a string. But since it isn't a real string type, there are lots of details in its use that are confusing to beginners.

Your "char*" variables are not arrays of char, so they are another step removed from being "strings". I'm sure you have seen examples in which a "char*" variable is successfully treated as if it were a string. But it is not inherently a string. You need to cover a lot of details in order to successfully pretend a "char*" is a string.

Any pointer in C might point to a single instance of whatever kind of thing it is declared to point to, or it might point to an array of them. That is another aspect of C that confuses most beginners. There is no difference in declaration between a pointer to a char and a pointer to an array of char.

A pointer in C doesn't point to anything until you set it to point to something. Making a "char*" variable means you have specified what kind of thing it points to, but you haven't made it point to any specific thing. Then you made the common beginner mistake of using the pointer to set the contents of the thing it points to, before setting the pointer to point to any specific place.

Your next big problem area is that you are using an input to a function as the mechanism for the function to deliver results. Maybe you have seen that done in some other language where objects are passed "by reference". In C, object are passed "by value", meaning they are copied as input to a function and discarded when the function is done. To get around that, you need to insert an extra level of indirection:

You have:
Code:
   lettura_studente(s1,
...
void lettura_studente(studente stud,
...
  stud.matricola = cod;
An extra level of indirection changes those to
Code:
   lettura_studente(&s1,
...
void lettura_studente(studente* stud,
...
  stud->matricola = cod;
The & where you pass a struct to a function tells it to pass the address of struct rather than the value. The * where the function receives the struct tells it to receive the address rather than the value. The -> instead of . where you access a field of the struct tells it to access by address.

Quote:
Originally Posted by psionl0 View Post
With a suitable size for STRING_LENGTH you could try
Code:
  char nome[STRING_LENGTH];
I agree. The original uses a "char*" instead of a char array for use instead of a string. Since strings don't actually exist, you need a char array instead of a string. Sometime you will need to use a "char*" as a pointer to a char array. But don't confuse yourself by using a "char*" instead of a char array. When you use a char*, the char array must also exist, it is just somewhere else. If the char array has no need to be somewhere else, then using a char* just creates extra work (which you then neglected to do). Keep it simpler and use a char array when that is all that is needed.

Quote:
Originally Posted by dwhitney67 View Post
void lettura_studente(studente& s);
That looks like you forgot you are answering a C question, not C++. That syntax in C++ changes the "pass by value" into a "pass by reference", so the rest of the uses of that variable (which were depending on pass by reference) could be left unchanged.

But C doesn't have pass by reference. Instead you need to pass the address. That requires changes in more places (as I showed above).

Last edited by johnsfine; 05-19-2013 at 12:34 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Getting segmentation fault(core dump) error gauravdev Linux - Newbie 2 10-12-2012 02:48 AM
segmentation fault (core dump) bhatia.ankur8 Linux - General 1 07-06-2010 04:58 AM
segmentation fault core dump shaiva Linux - Newbie 1 09-23-2009 11:04 AM
how to force a core-dump...segmentation fault johnpaulodonnell Programming 2 10-23-2008 06:05 AM
php core dump with segmentation fault ohcarol *BSD 9 10-14-2008 09:19 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:36 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration