Allocating memory with malloc getting error - c

int n;
scanf("%d",&n);
int *score;
score=(int *)malloc(sizeof(int)*n);
int i;
for (i=0;i<n;i++)
{
scanf("%d",sizeof(int)*i+score);
}
printf("ok");
In the above code I get an error but when I comment the last line printf the program runs correctly.
what is the problem??
(I want to give n number from user without using arrays)

Pointer arithmetic of the form score + i is already done in multiples of sizeof(*score). So when you write score + i * sizeof(int) you doubly multiply by the size of the items. You reach way beyond the bounds of the buffer.
Either write it simply as score + i, or if you insist on doing the multiplication yourself, be sure to cast to a character pointer type first:
(int*)((char*)score + i * sizeof(int))
Oh, and don't cast the result of malloc. C doesn't require it, and it's somewhat unidiomatic.

scanf("%d",sizeof(int)*i+score);
pointer arithmetic uses the pointer type, so here you are moving to sizeof(int)isizeof(int) bytes after score, instead just use scores+i.

Related

local and global arrays and segmentation fault

I'm having trouble with the following: I want to take a large number (cca. 15-digit) and turn it into individual digits and store them in an array. I will need these digits further on in the code. The problem is, if I declare the array outside the while loop, it stores the first four values, but then I get a segmentation fault. If I declare it within the loop, the code works as I want it to, but then I don't know how to move the array out of that loop, so that I could use it further. How can I solve this? This is what I've compiled:
unsigned long long card_num;
printf("Enter your credit card number:\n");
scanf("%llu", &card_num);
int count = 0;
while (card_num != 0)
{
int digits[count]; //declaring array into which digits will be stored
digits[count] = card_num%10; // get last digit, store it in array
card_num = card_num/10; //remove last digit
printf("Digit[%i] = %i\n", count, digits[count]);
printf("Number of digits: %i\n", count);
count ++;
}
In your code, for the very first iteration
int digits[count];
count is 0, which violates the constraints mentioned in spec. As per C11, chapter 6.7.5.2,
In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero. [....]
and
If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by *; otherwise, each time it is evaluated it shall have a value greater than zero
So, this is not a valid code.
As already mentioned, what you are doing is plain wrong.
There is several ways to solve this issue. The easiest would be to allocate an array at the beginning of your program with enough space for all your usecases with something like :
#define MAX_DIGIT 50
int digits[MAX_DIGIT];
Then you just have to check you are not going over this array by checking that count < MAX_DIGIT.
Another way would be using dynamic memory allocation using an int pointer int *digits and malloc (I let you google that) once you know the size of the array you'll need. You'll have to change a bit your code to know the number of digits before starting to get the digits as you need to allocate the memory before starting to store digits.
You could use realloc to keep a code similar to what you already have, but I wouldn't advise it as it is not efficient to realloc memory for each value that you add.
Your logic is fine.
What went wrong is that you tried to increase the length of a fixed-length array while iterating which is not allowed.
You should never change the length of a fixed-length array anywhere in the program.
However if you want to change the length of an array during runtime you must use the malloc and realloc functions to do so.
Check out this example:
//declarations
int *storeNum;
storeNum = (int *)malloc(1 * sizeof(int));
//logic
while(num != 0) {
if(i > 0)
storeNum = realloc(storeNum, (i+1) * sizeof(int));
storeNum[i] = num % 10;
num = num/10;
++i;
}
Here first I declared the array size initially as one and later incremented it using realloc function.
You also have the array size stored in i which you can use later in your code in loops.
But keep in mind that the digits will be stored in your array in reverse order.
Also, you shouldn't declare an array within a loop.
Since you have "declared" the array, each time the compiler enters the loop while iterating it will consider the array-declaration as a new array. That is all.

Why is not ampersand needed in the following code?

I understand that in C programming, 'scanf' is used with '&' for all variable tyles (int, float, char, ..) except string. Here is my program code. In front of 'scanf', why isn't '&' needed? And may I know more about scanf?
#include <stdio.h>
#define M 10
int main()
{
int i, n, sum = 0;
int a[M];
do{
printf("Input a positive number less than %d \n",M);
scanf("%d", &n);
}while (!(n >0 && n < M));
printf("Input %d numbers \n",n);
for(i=0; i<n ; i++){
scanf("%d",(a+i));
sum += *(a+i);
}
printf("Sum = %d \n",sum);
}
Because you have declared a as an array, an expression using that variable's name, on its own, will usually 'decay' to a pointer to the first element of the array (What is array decaying? - but see also the excellent comment added by Eric Postpischil for exceptions). This is similar to using a char[] string where, as you correctly noted, you don't need to use the & operator when passing it as an argument to scanf.
Adding i to this 'base address' of the a array will give the address of (i.e. a pointer to) the 'i'th element of the array.
Here is a decent tutorial on pointer arithmetic in C that you may find useful.
scanf usually takes the address of a variable it's reading into. a is already an address (an array that's decayed to a pointer) and i is simply an offset from that address.
This is equivalent to scanf("%d", &a[i]);; it does the same thing.
The & operator used before a variable in c returns the address of that variable. The base of an array already is the address you want. a+i like you're doing is using pointer arithmetic and changing the base address of the array by i

digit to integer in same order C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a function called fun(int num, int * array); which takes an int and int array as its arugments. I'm trying to convert int to the array.
When i run the program i don't get the array displayed properly
int fun(int num, int*array) {
int count =0;
while(num>0) {
num/= 10;
count++;
}
array[count];
// for loop works
}
When i print the array in the program i.e. everytime I run the program i get random digits.
What this line is supposed to do ?
array[count];
Since your integer array will change in your fun function, you have to allocate the memory (by using malloc, realloc, ...).
edit : plus, you already change the value hold by "num" when you count how many digit there are in "num".
Make a copy of "num" !
edit 2 : the more i look your function, the more it seem you will have problem using it.
Fisrt, you want to explode your integer into an array of int.
Okay, but integer have range, thus meaning integer have a maximum digit.
From my memories, there are 20 digit in an 64bit integer.
So you can simply use "int array[NB_DIGIT_INT_MAX];" with "#define NB_DIGIT_INT_MAX 21".
So, allocating is not necessary AND add complexity in your code (the caller will have to free after the function call).
Second, your fun function doesn't say how many case will hold your integer.
Let's say num = 12, your array will have "array[0] = 1, array[1] = 2", but how do you know where to stop ?
If num = 2345, how do you know that only the 4 first case in your array is legit ?
There are 2 way : You have an another variable that hold the actual size of the array, or you have a special value in your array that say "it's the end" (like '\0' for char array used as string).
You can use "-1".
Let's give a try, and don't hesitate to ask question if thing are unclear (english is not my motherlanguage)
Your array is not even allocated, this can not work as expected. You are even lucky not to have a segmentation fault. If you want to add an integer to an array making it grow, you need to allocate a larger array, copy the values and add the new one to the new array and delete the previous array, keeping array variable as a pointer to the new array. Moreover, you need to pass the size of the actual array as an argument of fun.
The count variable can be global, Initialize it outside all functions like this
short count;
The whole program could be modified like below
#include<stdio.h>
#include<stdlib.h>
short count;
void fun(int num, int **ptr) {
// You need a pointer to a pointer and return type can be void
int num_copy=num;
count=0; // Setting the count to zero
while(num_copy>0) {
num_copy/= 10; // Don't modify the original number
count++;
}
//Allocate enough memory to store the digits
*ptr=malloc(count*sizeof **ptr);
if(NULL==*ptr){
perror("Can't allocate memory");
exit(1);
}
// Then do the loop part with original num
for(int i=count -1; i>=0; i--) {
(*ptr)[i] = num%10;
num /= 10;
}
// By now you have an array 'array' of integers which you could print in main.
}
int main()
{
int number = 123456789;
int *array;
fun(number,&array); // &array is of type pointer to a pointer to integers
//Now print the individual digits
printf("Individual digits are : \n");
for(int i=count-1;i>=0;i--)
printf("%d\n",array[i]);
}
Looks to me like you are converting from an integer to digits. But I don't see where your code writes anything to the array.
If the array wasn't initialized before this, that would explain why it still contains random values.

int* vector accepts only the first given value

I'm experiencing some troubles with my code written in C. It's all about an int * vector intially declared and dynamically allocated but when it comes to filling it with data it stuck on the first element and won't increment the counter to fill the rest of the vector
my header file : instance.h
struct pbCoupe
{
int tailleBarre;
int nbTaillesDem;
int nbTotPcs;
int * taille;
int * nbDem;
};
my code : coupe.c
pb->taille = (int*) malloc (pb->nbTaillesDem * sizeof(int));
pb->nbDem = (int*) malloc (pb->nbTaillesDem * sizeof(int));
while (i < pb->nbTaillesDem)
{
fscanf_s(instanceFile,"%s",data,sizeof(data));
pb->taille[i] = atoi(data); //<-- here is the problem !! it only accept the first value and ignore all the rest
printf("%s\n",data);
fscanf_s(instanceFile,"%s",data,sizeof(data));
pb->nbDem[i] = atoi(data); //<-- the same problem here too !!
printf("%s\n",data);
i++;
}
Your interpretation of sizeof is wrong, since data is the buffer that the string is being parsed into.
It returns the size of the the variable, not the size of the the what the variable (or namely a pointer) points to
Strings in C are all pointer to the size would be 4 bytes on a 32-bit system, 8 on a 64-bit.
Since it prints all the number it reading more numbers that intended with each loop iteration 4 bytes = 4 characters, atoi on parses the first integer and returns,
EDIT: If it is a buffer array, sizeof returns the size of the array.
You need to make sure you are only reading in a single number per iteration of the loop to solve this issue.
If you don't care for the literal string, best thing you can do is use:
fscanf(instanceFile, "%d", ((pb->taille) + i)));
//and store the integer into the index right away
//last param same as &pb->taille[i]

Reading floats into an array

How could I read let's say 10 floats and store them in an array without wasting any memory?
int size = 10;
float vet[size];
for(i = 0; i < size; i++){
scanf("%f", &vet[i]);
}
As simple as it could be :)
Aha. It's not reading the floats that's the problem, it's the memory. You read in i, and you need an array that holds exactly i floats.
This really does smell like homework, which is fine, but I'm too much the teacher to give you the full answer. So I'll tell you, what you need is a C function named malloc() and a C operator (it looks like a function but it's actually built into the language) named sizeof.
Have a look at this tutorial.
Yup, you got it there. Here's the code from your comment, formatted.
int n,index;
float temp;
scanf("%d",&n);
float *pValues=(float *)calloc(n,sizeof(float));
for(index=0;index<n;index++) {
scanf("%f",&temp);
*(pValues+index)=temp;
}
I'd do it with two changes:
Its more idiomatic to use malloc for anything besides characters
In C, arrays and pointers have a very close relationship; in fact *(pValues+index) is exactly equivalent to pValues[index].
So I'd rewrite this as:
int n,index;
float temp;
scanf("%d",&n);
float *pValues=(float *)malloc(n*sizeof(float));
for(index=0;index<n;index++) {
scanf("%f",&temp);
pValues[index]=temp;
}
Let's look at one more transformation of the code. You have pValues, which is a pointer to float. You have &temp, which is also a pointer to float, because & is the address-of operator and temp is a float. AND, you're just doing pointer arithmetic with your index. So, we could rewrite this one more time as:
int n,index; // Don't need temp
scanf("%d",&n);
float *pValues=(float *)malloc(n*sizeof(float));
for(index=0;index<n;index++) {
scanf("%f",pValues+index);
}
Now, quiz question: what would happen if you made the loop
for(index=0;index<n;index++) {
scanf("%f",pValues++);
}
You'll have to be more specific about the problem.
Unless you have something else that you need to do with these numbers, then the easiest way to save memory is not to store them in an array to begin with.
It sounds like what you want is something like.
sum = 0;
do
read current
sum += current
while (you haven't yet read 10 numbers);
The answer to your question is that you cannot add things to an array and expect the array to use any memory.
float arr[10];
for(i = 0; i < 10; i++){
scanf("%f", &arr[i]);
}
I know, it's like the above, but doesn't use the extra int in case it's not optimized out. hehe
To use even less memory us the code below. They're all read into an array, but only the last one to be read in is in the array:
float arr[1];
for(i = 0; i < 10; i++){
scanf("%f", &arr[0]);
}
sounds like homework.
read the number of floats from the input.
multiply that by the size of an individual float
allocate that exact number of bytes storing the address in a pointer to floats
have a loop read in the floats from the input
have a loop that adds up all the floats in the array
My guess here is the homework lesson is to realize the connection between the term pointer and array, although you can do this without any array indexing, but your question implies that you have to use an array.

Resources