Today I was messing around with malloc and integer pointer. The program is setup so it allocates a memory location to an integer pointer and then fills the memory location with bunch of integers like an array and then print all the integers. The problem is when ever it finishes running it crashes. And I suspect that malloc is causing the issue.
Here is the code
#include<stdio.h>
#include<stdlib.h>
int main(){
int *name,x;
char y;
name=malloc(sizeof(int));
for(x=0;x<500;x++){
name[x]=x;
}
for(x=0;x<500;x++){
printf("%d ",name[x]);
}
scanf("%c",&y);
free(name);
return 0;
}
please help.
Thanks!
name = malloc(sizeof(int));
is the problem. That way you can store only one int in the array. Try
name = malloc(sizeof(int) * 500);
instead.
Uh, "malloc()" isn't crashing your program.
You're crashing your program :)
SUGGESTIONS:
Check for "name=malloc()" returning NULL (i.e. check for errors).
Don't allocate space for 1 int ("sizeof(int)" is probably four bytes), then try to write 500 ints :)
Don't litter your code with "magic numbers" like "500" - use a constant instead.
SUGGESTED CHANGES:
#include<stdio.h>
#include<stdlib.h>
#define NELMS 500
int main(){
int *name = NULL,x;
char y;
name=malloc(sizeof(int) * NELMS);
if (!name) {
perror ("Unable to allocate memory!");
return 1;
}
for(x=0;x<NELMS;x++){
name[x]=x;
}
for(x=0;x<NELMS;x++){
printf("%d ",name[x]);
}
scanf("%c",&y);
free(name);
return 0;
}
You are allocating memory to store only one int. What you need is:
name=malloc(500*sizeof(int));
Related
I just installed visual studio 2013 and gonna try a simple code. So I write this one:
int main(void) {
int length = 0;
int *array ;
printf("Enter the number of input: ");
scanf_s("%d", &length);
printf("%d", length);
for (int i = 0; i < length; i++){
scanf_s("%d", array + i);
}
printf("shoting ........ ");
getc;
return 0;
}
When I compile this code, it says local variable "array" is not initialized .
Am I missing something ?
The statement int *array ; declares a pointer. But you don't know where it points to. You can allocate some space using memory allocation functions like malloc() etc. or make it point to some other pre-allocated space. As you are asking user for the input length (i.e. don't know your memory requirement at compile time), dynamic memory allocation like malloc() would be the way to go.
Note: This answer is applicable if you are compiling in C,not C++
int *array;
Declares a pointer of type int*. Since it is not initialized, it points to some random location. This is what the compiler is trying to tell you. Just allocate memory dynamically using malloc. Add
array=malloc(length*sizeof(int));
Just after the first scanf_s to allocate enough memory. Note that you need to include stdlib.h to use malloc.
Also change
getc;
To
getchar();
It is also a good idea to check the return values of malloc,scanf_s etc to see if they are successful.
You need to Initialize the array
such as
int *array = maloc(sizeof(int) * 100);
or
int *array = new int[];
I have written the following program:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
void inttobusn(int val, int n, char* bus)
{
int i;
unsigned int digit;
for (i=0; i < n; i++) {
digit = pow(2, (n-1-i));
if (digit <= val) {
val -= digit;
bus[i] = '1';
//printf("hello %c",bus[i]);
} else {
bus[i] = '0';
}
}
}
main(){
char* bus;
inttobusn(37,8,bus);
int i=0;
//printf("%s",bus);
for(i=0;i<12;i++){
printf("%c",bus[i]);
}
}
But on running it doesn't print the elements of the array bus. It doesn't print anything. I am unable to figure out what is wrong. Please could someone point out?
Your code is buggy! you don't allocate memory for the bus[] array, and are trying to access values at garbage location as e.g bus[i] = 0; -- Undefined Behavior in C standard, Undefined means you can't predict how your code will behave at runtime.
This code compiled because syntax-wise the code is correct but at runtime the OS will detect illegal memory access and can terminate your code. (interesting to note: as OS detects memory right violation by a process -- An invalid access to valid memory gives: SIGSEGV And access to an invalid address gives: SIGBUS). In the worst case your program may seem execute without any failure, producing garbage results.
To simply correct it define bus array as char bus[N]; else allocated memory dynamically using void* malloc (size_t size);
Additionally, suggestion to your from #Lochemage and #Ran Eldan:
You need to declare bus with a specific size, like char bus[12]. It has to be at least large enough to fit 12 chars because your for loop at the end is iterating through that many (and you can check your code working with this suggestion #codepade).
Also there is no return type to main() in your code, its should be int main(void).
There is no memory allocated to bus so this is an undefined behavior. Either write
char bus[some sufficient size];
or use malloc, realloc to reserve memory.
You didn't initialize you bus variable.
char* bus = malloc(8 * sizeof(char));
I am trying to create a function that allocates memory of a certain specified size. In the main, I create the pointer and then send the pointer and the size to the function for memory to be allocated. For some reason it causes all sorts of problems. My program works smoothly if I use the malloc in the main, but not through the function.
int main(void){
int * pointer;
int array_size = SIZE;
...
allocate_memory(&pointer,array_size);
...
free(pointer);
}
allocate_memory(int *pointer,int size){
*pointer = (int *)malloc(size*sizeof(int));
if(!(*pointer)){
printf("Memory allocation fail!");
exit(0);
}
The problem now is that it gives me an error when I try to free the memory.
I would appreciate it if the solution will come with a short explanation. I am starting to be very confused about how these pointers and castings are working.
Thanks in advance!
There were many errors in your program which I am pointing out:
You need to #define the macro SIZE as otherwise the program just won't know what it is.
It's better to declare a prototype of the function allocate_memory() so that any discrepancy in type of arguments or return type is detected
You had passed &pointer as an argument to allocate_array() in main().For this it is necessary to define the function as allocate_memory(int **pointer,int size) instead of allocate_memory(int *pointer,int size) which you have done.
if(*pointer==NULL) implements the condition in a much simpler way and serves just the same purpose.
Use exit(1) for unsuccessful termination as exit(0) is used to denote successful termination.
Never ignore warnings.It's not a good practice.
Here's the corrected code.It compiles well without warnings and does the job (memory allocation) as intended.
#include<stdio.h>
#include<stdlib.h>
#define SIZE 30
void allocate_memory(int**,int);
int main(void){
int * pointer;
int array_size = SIZE;
allocate_memory(&pointer,array_size);
free(pointer);
}
void allocate_memory(int **pointer,int size)
{
*pointer = malloc(size*sizeof(int));
if(*pointer==NULL)
{
printf("Memory allocation fail!");
exit(1);
}
else
printf("\nMemory allocation successful");
}
I am solving a problem on USACO. In the problem, I have to take two strings as inputs and calculate the numerical values modulo 47. If the values are same, then GO is to be printed otherwise STAY has to be printed. The initial numerical value will be calculated by taking the product of the numerical values of the alphabets ( 1 for A and similarily 26 for Z ) and then the final number will be calculated by using modulo.
My program is being compiled withour any error and running well on my computer. However, it is showing a segmentation fault as the execution error by the grader computer. The program and the output is as follows:-
Program:-
#include<stdio.h>
#include<string.h>
main()
{
int cal(char *ptr);
char *comet,*group;
int a,b;
scanf("%s",comet);
a=cal(comet);
scanf("%s",group);
b=cal(group);
if(a==b)
printf("GO");
else
printf("STAY");
return 0;
}
int cal(char *ptr)
{
int i=0,c,prod=1,mod;
while(ptr[i]!='\0')
{
if(ptr[i]>='A'&&ptr[i]<='Z')
{
c=ptr[i]-'#';
prod=prod*c;
i++;
}
}
mod=prod%47;
return mod;
}
OUTPUT:-
My question is how to pinpoint the segmentation fault. I have read about this fault but don't know what to do in this program. Any help would be great.
char *comet,*group;
int a,b;
scanf("%s",comet);
comet pointer is uninitialized. You need to allocate memory and makes comet points at this allocated memory otherwise scanf will write bytes in a random location which will likely crash your system.
Both comet and group are uninitialized pointers which do not have any memory allocated for storing the input strings.
Your program should be doing this at least. Increase the size of MAX_STRING_SIZE per your needs.
#define MAX_STRING_SIZE 100
char comet[MAX_STRING_SIZE];
char group[MAX_STRING_SIZE];
You still have the risk of buffer overflow with scanf. You can look at this post for some possible ways to avoid buffer overflow.
Your while is highly suspect: i is increased only if ptr[i] is an uppercase letter. What should happen if it isn't? How does If you have an ironclad guarantee that only uppercase letters will show up, you could write:
prod = 1;
while(*ptr) {
prod *= *ptr - 'A' + 1;
ptr++;
}
(Your ptr[i] - '#' had me scratching my head until I broke out ascii(7). I believe my version is clearer, and any halfway competent compiler will give the same code.)
Or, more idiomatically:
int cal(char *ptr)
{
int prod = 1;
while(*ptr)
prod *= *ptr++ - 'A' + 1;
return prod % 47;
}
Just be careful that the product does't overflow, perhaps do the modulus each character:
int cal(char *ptr)
{
int prod = 1;
while(*ptr) {
prod *= *ptr++ - 'A' + 1;
prod %= 47;
}
return prod;
}
You never allocate space for comet or group. Use malloc() or similar to set aside memory for those pointers, so that you can actually store something in what they point to.
#define MAX_STRING_LENGTH 256
...
char *comet, *group;
int a, b;
comet = NULL;
comet = malloc(MAX_STRING_LENGTH);
if (!comet) {
fprintf(stderr, "ERROR: Could not allocate memory to comet\n");
return EXIT_FAILURE;
}
scanf("%s",comet);
/* repeat for other pointers, as needed */
/* ... */
/* free up allocated memory at the end of the program to help prevent leaks */
free(comet);
comet = NULL;
"running well on my computer" this is not possible in your case as you are not using any compiler specific code (like getch for turbo c)
You didn't allocate memory for storing the string.The pointers comet and group don't point to anything.scanf requires an address to write the input but the pointers do not contain an address and that is why you are getting a segmentation fault.
You can allocate memory using malloc (or calloc) or you can define a character array.
The corrected code is
#include<stdio.h>
#include<string.h>
#define MAXLENGTH 100
int main()
{
int cal(char *ptr);
char comet[MAXLENGTH],group[MAXLENGTH];
int a,b;
scanf("%s",comet);
a=cal(comet);
scanf("%s",group);
b=cal(group);
if(a==b)
printf("GO");
else
printf("STAY");
return 0;
}
int cal(char *ptr)
{
int i=0,c,prod=1,mod;
while(ptr[i]!='\0')
{
if(ptr[i]>='A'&&ptr[i]<='Z')
{
c=ptr[i]-'#';
prod=prod*c;
i++;
}
}
mod=prod%47;
return mod;
}
I'm just starting on the road the learning C, and ran into some difficulty:
The code listed below is giving me the following error:
Attaching to program: `/workfolder/cocoa/c_stuff/bookshelf/build/Debug/bookshelf', process 1674.
Cannot access memory at address 0xa0df194
Cannot access memory at address 0xa0df194
// code start
#define MAX_NAME_LENGTH 200
#define MAX_AUTHOR_LENGTH 200
#define MAX_DESCRIPTION_LENGTH 1000
#define MAX_PUBLISHER 200
#define MAX_ISBN 50
//structures<
typedef struct {
char title[MAX_NAME_LENGTH];
char author[MAX_AUTHOR_LENGTH];
char ISBN[MAX_ISBN];
char description[MAX_DESCRIPTION_LENGTH];
char publisher[MAX_PUBLISHER];
} Book;
void getUserInput(Book *s[])
{
printf("what is the book's title ?\n");
fgets(s[book_count]->title, MAX_NAME_LENGTH, stdin);
printf("what is the author's name?\n");
fgets(s[book_count]->author, MAX_AUTHOR_LENGTH, stdin);
printf("what is the ISBN?\n");
fgets(s[book_count]->ISBN, MAX_ISBN, stdin);
printf("write a short description\n");
fgets(s[book_count]->description, MAX_DESCRIPTION_LENGTH, stdin);
printf("what is the book's publisher\n");
fgets(s[book_count]->publisher, MAX_PUBLISHER, stdin);
printf("want to add another book ? Y\\N\n");
book_count++;
if(tolower(fgetc(stdin)) == 'y')
{
return getUserInput(s);
}
else
{
return;
}
}
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
if((book_shelf[0] = (Book *)malloc(sizeof(Book))) == NULL)
{
exit(1);
}
getUserInput(book_shelf);
return 0;
}
The code compiles properly, and the function runs fine the first time (all the questions get asked and the struct receives the data); but when the user types 'y' to add another book, the mem error occurs.
Any ideas where the error is happening?
Thanks in advance!
You've only ever allocated memory for the first book in main - after that it tries to write to the next slot in the array, which doesn't point to an allocated block of memory, giving you a seg-fault. You're going to have to allocate memory for each book you want to read in.
In addition, since C doesn't know how long an array is, you have to pass that information along into function calls. (And I don't see where you're defining book_count.)
You might try something along these lines:
void getUserInput(Book *s[], int *book_count, int max_book_count)
{
if (book_count == max_book_count) return; // If we've filled all the slots, we can't add anymore without causing trouble.
s[book_count] = malloc(sizeof(Book));
..
if(tolower(fgetc(stdin)) == 'y')
{
(*book_count)++;
getUserInput(s, book_count, max_book_count);
}
return;
}
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
int book_count = 0;
getUserInput(book_shelf, &book_count, 100);
// Make sure to free all the malloc'd data
}
Even better in this situation, would just be using a loop and skipping the whole recursion step.
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
char response = 'y';
int book_count = 0;
while (book_count < 100 && response == 'y')
{
book_shelf = malloc(sizeof(Book));
response = getUserInput(book_shelf[book_count++]);
}
// make sure to free all the allocated data!
}
char getUserInput(Book *book)
{
// write input straight to book
printf("what is the book's title ?\n");
fgets(book->title, MAX_NAME_LENGTH, stdin);
...
return tolower(fgetc(stdin));
}
Unless I'm reading something wrong, you haven't defined book_count before using it as an array subscript.
Within main, you allocated on the stack an array of 100 pointers to the Book Structure. I believe it was your intent to allocate 100 structures and then pass the address to that block of structures to getUserInput
Change main to:
Book book_shelf[100];
...
getUserInput(book_shelf);
...
EDIT: OOPS Missed the single Book malloc mentioned in the earlier post. That ones Correct for the first book. If you edit as above and eliminate the
if (book_shelf[0]...) check, you'll accomplish your intended results
You allocate just space for the firstbook, not for the others (malloc in main)
I guess there is some code missing, no declaration and initialization of book_count
You should use loops instead of recursion
Use not recursion but loops for this kind of repetition
Recursion is probably overkill for this problem where a simple do { ... } while(user keeps answering yes) would do. However the problem you having is in main with your Book *book_shelf[100]. There are several ways you could solve this problem.
First change it to an array of Book's like samills suggests:
Book book_shelf[100];
and then change your getUserInput to something like this:
getUserInput(Book *book_shelf, int offset, int length) {
if(offset < 0 || offset >= length) {
return;
}
//...
return getUserInput(book_shelf, offset + 1, length)
}
Or you could use your existing code and change you getUserInput function to look something like this and remove the malloc from main:
getUserInput(Book *book_shelf) {
book_shelf[book_count] = (Book*)malloc(sizeof(Book));
// ...
}
props for correct use of the sizeof operator (I see that thing misused so often it makes my eyes bleed).
As in Josh's answer, by adding the following lines to your code should make it work:
book_count++;
if(tolower(fgetc(stdin)) == 'y')
{
if((book_shelf[book_count] = (Book *)malloc(sizeof(Book))) == NULL)
{
printf("Cannot allocate memory for Book");
exit(1);
}
return getUserInput(s);
}
else
{
return;
}
However, I encourage you not to use the recursive function for getting input. Recursive can lead to difficulties in debugging. You may consider using normal loop instead.
Note: I'm assuming the book_count is global variable which has been initialized to 0
thanks a lot for the replies!
I realized that I hadn't malloc-ed enough memory to handle more then one element of the struct array (Exactly what Josh is saying). So essentially:
Book *book_shelf;
if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code
so the second time around I would hit a memory issue.
thanks again!
Looks like your still doing it wrong:
Book *book_shelf;
if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code
book_shelf is only the size of a pointer. When you do the malloc you only allocate one Book at a time. This is wrong. You need to allocate contiguous memory for an array of Book objects all in one instanciation of an array.
Like
Book book_shelf[100];
not
Book *book_shelf[100];
or using malloc, use your pointer to point to an array instanciated using
100*malloc(sizeof(Book)).
You may get lucky that no other heap memory is allocated in between your malloc(sizeof(Book)) calls and that the memory management system is alocating contiguous memory by default. Also, book_shelf will only point to the last malloced Book structure, not the first one as you indicated you want in your original question.
Josh is also not allocating enough memory at one time. Use a linked list if you want to keep extending elements to the end of your book_shelf one-by-one.
factorial with pointer and recursion
#include<iostream.h>
#include<conio.h>
int show(int *p)
{
int f;
int x=*p;
if(*p==1) //boundry checking for recursion
return 1;
else
f=x*show(&(--*p)); //this code is similar to f=x*show(n-1); with non-pointers
return f;
}
void main()
{
int a=6;
int b=show(&a);
cout<<b;
getch();
}