Getting segmentation fault when giving input to structure members on run time - memory

I have written a small code to fetch info of 'n' number of students.
But after running the program, I'm getting a segfault. Please find the code below.
struct students
{
char name[20];
int age;
int id;
}student[100];
int main()
{
int count;
int no_students;
printf("Enter no of students");
scanf("%d",&no_students);
for (count = 1 ; count <= no_students ; count++)
{
printf("Enter the details for student%d\n",count);
printf("Name:");
scanf("%s",student[count].name);
printf("Age:");
scanf("%d",student[count].age);
printf("ID:");
scanf("%d",student[count].id);
}
return 0;
}
root#debian:/home/renga/C_code# ./nike
Enter no of students3
Enter the details for student1
Name:renga
Age:12
Segmentation fault

Got the problem, missed reference operator in scanf.
printf("Age:");
scanf("%d",&(student[count].age));
printf("ID:");
scanf("%d",&(student[count].id));

This may not be the right group to ask C language help/syntax question. I would recommend reading a good C programming language book ex: http://www.cprogramming.com/tutorial/c-tutorial.html
Having said that, the problem is, you are trying to read your int data type (age & id) values incorrectly. You need to read the values into the address of the variables as shown below...
scanf("%d",&student[count].age);

Related

What function would you use to list the symbols?

Is there a way to set a condition that includes a list of currency symbol pairs and be alerted when that condition is met? What function would you use to list the symbols? Thanks in advance. The following code gives you a rough idea of what i'm trying to do.
for(i=0;i<Bars; i++)
{
//Want a list of symbols to scan multiple currency pairs for the following condition
if(Symbol("EURUSD";"AUDCAD";"USDJPY")Close[i+1]>Close[i+2])
{
a=a+1;
//This is what I want to happen if condition is met
Alert(Symbol()+" 1");
}
You can use SymbolsTotal and SymbolName to get a list of all the symbols in Market Watch. The following code should give you a start (although it will be permanently giving alerts, I think you need to check exactly what you want alerts for) .
for(int i=0; i<SymbolsTotal(true); i++)
{
string currencySymbol=SymbolName(i,true);
int a=0;
for(j=0; j<iBars(currencySymbol,0); j++)
{
if(iClose(currencySymbol,0,j)>iClose(currencySymbol,0,j+1)) a++;
{
if(a>0) Alert(StringConcatenate(currencySymbol,":",IntegerToString(a)));
}

Converting the result from JSON GENERATE to EBCDIC

For one of my requirements I need the JSON GENERATE function in COBOL 6. My problem is, that it returns UTF-8, but I need the data in EBCDIC (CCSID 1140). Is there a way to convert this? Every solution I found uses national data types, but I have to use the NODBCS compiler option, so those don't work.
I do apologize for not first asking a question (but I am too new to StackOverflow to allow that.) The question would be "do you have C++ and can you link C++ with your COBOL?" I just tried this program:
#include <iconv.h>
class myConv
{
public:
static myConv globalConv;
size_t conv(char ** restrict f, unsigned int * restrict flen,
char ** restrict t, unsigned int * restrict tlen)
{
if (ok_)
{
return iconv(cd_, f, flen, t, tlen);
}
else
{
return (size_t)-1;
}
}
private:
myConv()
{
cd_ = iconv_open("1047", // EBCDID
"1208"); // UTF-8
ok_ = (cd_ != (iconv_t)-1);
// possibly indicate what the error is
}
~myConv()
{
if (ok_)
{
if (iconv_close(cd_) != 0)
{
// possibly indicate what the error is
}
}
}
bool ok_;
iconv_t cd_;
};
myConv myConv::globalConv;
extern "C" bool CNV(char * f, unsigned int flen,
char * t, unsigned int tlen)
{
return myConv::globalConv.conv(&f, &flen,
&t, &tlen) != (size_t)-1;
}
and the COBOL call looked like this:
json generate result from grp
call "CNV" using by reference result,
by value length of result,
by reference convertedres,
by value length of convertedres,
returning cres
and cres is a PIC S9(9) COMP data item which will have a non-zero value of the conversion succeeded.
Again, I apologize for not first asking if C++ is a possibility. (Or even C. The code could be easily done in C.) Also, the result is not quite perfect owing to the JSON GENERATE result being zero filled.

Assign value is garbage or undefined

I have posted screenshot of my error code.
heights output
please any one can help me?
I think the static analyzer is not seeing how _numberOfColumns can become non-zero, and hence its insistence that garbage is being assigned. You need to check that you are actually providing some means for _numberOfColumns to become non-zero.
Generally when I am writing loops that want to find the largest or the smallest value, I initialize the size variable to the largest (if I want the smallest) or smallest (if I want the largest) amount, and I think this will solve most of your issues:
float shortestHeight = FLT_MAX;
for (unsigned i = 0; i < _numberOfColumns; i++)
{
// etc.
}
The analyzer is correct. Your code will access garbage memory if _numberOfColumns is 0, thus allocating 0 bytes for heights, making heights[0] garbage. The analyzer doesn't know what values _numberOfColumns can have, but you can tell it by using assert(_numberOfColumns>0).
Take this C program for example:
int main(int argc, const char * argv[])
{
int n = argc-1;
int *a = malloc(n*sizeof(int));
for (int i=0; i<n; i++) {
a[i] = i;
}
int foo = a[0];
free(a);
return foo;
}
the size of a is determined by the number of arguments. If you have no arguments n == 0. If you are sure that your program (or just that part of your program) will always assign something greater than 0 to a, you can use an assertion. Adding assert(n>0) will tell the analyzer exactly that.

segmentation fault when printing a list of values from the memory

I am trying to make a small application that prints the content of a number of consecutive memory locations. As an indication of where the program is in the memory, I am printing the memory location of the main function and of a dummy variable.
In a first column, I want to print the address. In a second column, I want the contents of this address and the content of the 9 addresses behind it. In a third column, I want to print the byte value as a char, if it is printable. If it is not printable, I want to print a dot. In the rows under the first, I do exactly the same.
At startup, a number of values to print can be entered. If a positive value is entered, the addresses will increment, if a negative value is entered, the addresses will decrement.
To quickly see where I want to get to, you could run the code and enter for example 20 bytes to dump and use the address of the dummy as a starting address.
So far, my code only works for positive values. When I enter a negative number, I get a segmentation fault, but I can't figure out why. I tried to find the error in Valgrind, without success.
Some help would be greatly appreciated!
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define NUMBER_OF_BYTES 10
void showAddresses(void);
void printMemory(void);
void getDumpSize(void);
char* dummy; // dummy is een pointer naar een int
signed int dumpSize; // how many bytes have to be dumped?
signed int upDown; // do I need to go up or down?
int main(void)
{
dummy = (char *) malloc (sizeof(unsigned char));// memory allocation
showAddresses(); // prints the main function address and a variable address
getDumpSize(); //
printMemory(); //
free(dummy); // free memory
return 0; // end the main function
}
void showAddresses(void)
{
printf("Main function address is %p \n", main);
printf("Dummy variable address is %p \n",(void*)dummy);
}
void getDumpSize(void)
{
printf("Enter number of bytes to dump <negative or positive>:");
scanf("%d",&dumpSize);
if(dumpSize<0)
{
upDown = -1; // count down
printf("upDown was set to -1\n");
}
else
{
upDown = 1; // count up
printf("upDown was set to +1\n");
}
}
void printMemory(void)
{
int input;
printf("Enter the address:");
scanf("%x", &input); // enter the input
printf("Address \tBytes \t\t\t\tChars \n"); // print the table header
printf("--------- \t----------------------------- \t---------- ");
int i;
unsigned char* address; //
for(i=0;i<abs(dumpSize);i++)
{
address = (unsigned char*) (input+(i*upDown)); // make the address to print
if( (i%NUMBER_OF_BYTES) == 0) // show the address every 'i*NUMBER_OF_BYTES' times
{
printf("\n%p \t", (void*) address);
}
printf("%02x ", *address); // print as a 2 number hex and use zero padding if needed
if( (i%NUMBER_OF_BYTES) == (NUMBER_OF_BYTES-1) )// print the char list for every value (if printable)
{
printf("\t");
int j;
for(j=(NUMBER_OF_BYTES-1);j>=0;j--)
{
address = (unsigned char*) (input+(i*upDown)-j);
if(isprint(*address)==0)// print a dot if the byte value is not printable
{
printf(".");
}
else
{
printf("%c",*address); // print the byte value as a char, if printable
}
}
}
}
}
Your segmentation fault is likely coming from attempting to access memory outside of your program's scope. The address in "dummy" is the first malloc from your program, so it represents (possibly) the first "area" of memory available to your program. Going up from there might be keeping you in program space (hence the lack of seg fault), but going backward might be driving you into a restricted memory area. Out of curiosity: what is the memory address returned for your "dummy" malloc? Is the number even large enough to go backward without going negative? (I'm wondering if your program sees the true system memory map or a paged map that is already sand-boxed for programs.)

C Programming: Linked Lists

I'm writing a program using linked list (such a nightmare).
Anyway, the purpose of the program is to enter 8 characters and have the program print the characters back out to you and also print the characters back out in reverse order, using linked lists of course.
I got this so far. There's a lot wrong with it (i think).
Problems are
When asking for characters from the user it should read in the amount of characters automatically without having to ask for how many characters
Also, when it it compiles it prints gibberish to the screen, for example I just ran it and it printed
¿r
(àõ($ê¿¿
a¿r
(àõ($ê¿¿
¿r
(àõ($ê¿¿
b¿r
(àõ($ê¿¿
Lots of help needed here. It would be so much appreciated!
Code of course
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define strsize 30
typedef struct member
{
int number;
char fname[strsize];
struct member *next;
}
RECORD;
RECORD* insert (RECORD *it);
RECORD* print(RECORD *it, int j);
int main (void)
{
int i, result;
RECORD *head, *p;
head=NULL;
printf("Enter the number of characters: ");
scanf("%d", &result);
for (i=1; i<=result; i++)
head=insert (head);
print (head, result);
return 0;
}
RECORD* insert (RECORD *it)
{
RECORD *cur, *q;
int num;
char junk;
char first[strsize];
printf("Enter a character:");
scanf("%c", &first);
cur=(RECORD *) malloc(sizeof(RECORD));
strcpy(cur->fname, first);
cur->next=NULL;
if (it==NULL)
it=cur;
else
{
q=it;
while (q->next!=NULL)
q=q->next;
q->next=cur;
}
return (it);
}
RECORD* print(RECORD *it, int j)
{
RECORD *cur;
cur=it;
int i;
for(i=1;i<=j;i++)
{
printf("%s \n", cur->fname);
cur=cur->next;
}
return;
}
You have:
in insert:
char first[strsize];
scanf("%c", &first); /* note the %c */
strcpy(cur->fname, first);
in print
printf("%s \n", cur->fname);
You should have %s instead of %c and therefore change &format to format in the argument list, as format itself represents the address of the location the string is to be stored.
So the scanf call should be like below
scanf("%s", first);
Another thing. If you have specified a return type in the print function then you should return something, or make it return nothing (declare return type as void). This will not pose any problem in this case although.
Read the warning messages which the compiler throws to you and you would see the compiler actually had answered your questions.
You need to do some redesigns i think. For example to traverse the linked list you do not need to counter 'j'. you can detect the list termination by inspecting if the next link is NULL or not.
Your question was to print the characters or strings in reverse, so you need to write some other print function than what you have wrote.

Resources