scanf from function to array - c

I am trying to scanf values to an array from another function using pointer to pointer. Here's the code:
int initialize(int **arr, int count);
int main()
{
int count;
int *numbers;
scanf("Enter the amount of numbers to enter: %d", &count);
initialize(&numbers, count);
free(numbers);
return 0;
}
int initialize(int **arr, int count)
{
int i = 0;
*arr = calloc(count, sizeof(int));
while(i < count)
{
printf("Nr. %d: ", i + 1);
scanf("%d", &arr[i]);
i++;
}
return 0;
}
It allocates the memory correctly, however, there seems to be a problem inside scanf function in initialize so it crashes after reading in first 2 numbers. Could you help solve it?

arr is a pointer to pointer to int, so 1st make it a pointer to int (before using it like an array) by doing *arr.
So this
scanf("%d", &arr[i]);
should be
scanf("%d", &(*arr)[i]);
or its shorter equivalent
scanf("%d", *arr + i);
Unrelated, but in C it should be at least
int main(void)
Unrelated^2: Sizes and indexes in C best are defined using size_t (coming with stdlib.h).
So the relevant part of your code would look like this:
int main(void)
{
size_t count;
int *numbers;
scanf("Enter the amount of numbers to enter: %zu", &count);
...
int initialize(int **arr, size_t count)
{
size_t i = 0;
*arr = calloc(count, sizeof(int));
while (i < count)
...
Last not least the code misses error checking for the relevant functions:
scanf()
calloc()
Error checking (along with logging the errors) is debugging for free!

Related

Qsort of dynamically allocated array of numbers

#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b);
int main(void) {
int input;
scanf("%d", &input);
int* array = (int *) calloc(input, sizeof(int));
for (int i = 0; i < input; i++) {
scanf("%d", &array[i]);
}
qsort(array, sizeof(array)/sizeof(int), sizeof(int), compare);
for (int i = 0; i < input; i++) printf("%d ", array[i]);
return 0;
}
int compare(const void *a, const void *b)
{
int num1 = *(int *)a;
int num2 = *(int *)b;
if (num1 < num2) return -1;
if (num1 > num2) return 1;
return 0;
}
I am still a student of C language basics. It might be a very basic question because you haven't learned it all right.
I'm trying to sort a dynamic array.
I created and sorted a dynamic array, but looking at the result, there is no sorting at all. What is the problem?
The value for nitems (second parameter) passed to qsort is wrong.
Your program works if you change the qsort call to:
qsort(array, input, sizeof(int), compare);
sizeof can't be used on malloc'd memory the way you're doing it. It only
works on fixed sized arrays like int array[10]. Because at compile time the compiler knows how many elements there are.
sizeof(array)/sizeof(int) // <= won't work. is equivalent to
sizeof(int*) / sizeof(int)
The result is probably 1. So you're qsorting the first element only

Can somone please explain this to me

For n=3 and a={1,2,3},b={4,5,6} its supposed to calculate 1*4+2*5+3*6.
I don't understand why does it work because p is a pointer and p=produs(a,b,n) means that the address of p becomes the value returned by produs.
#include <stdio.h>
#include <conio.h>
void citire(int *x,int *n)
{
for(int i=1; i<=*n; i++)
scanf("%d",&x[i]);
}
int produs(int *a,int*b,int n)
{
int produs=0;
for(int i=1;i<=n;i++)
produs=a[i]*b[i]+produs;
return produs;
}
int main()
{
int n;
int*p;
scanf("%d",&n);
int *a=(int*)malloc(n*sizeof(int));
int *b=(int*)malloc(n*sizeof(int));
citire(a,&n);
citire(b,&n);
p=produs(a,b,n);
printf("%d",p);
return 0;
}
When you do:
size_t size = 10;
int* x = calloc(size, sizeof(int));
You get an array x with 10 items in it, indexed 0..9, not 1..10. Here calloc is used to make it abundantly clear what's being requested instead of doing multiplication that can be mysterious or obtuse.
As such, to iterate:
for (int i = 0; i < size; ++i) {
x[i] ...
}
You have a number of off-by-one errors in your code due to assuming arrays are 1..N and not 0..(N-1).
Putting it all together and cleaning up your code yields:
#include <stdio.h>
#include <stdlib.h>
void citire(int *x, size_t s)
{
for(int i=0; i < s; i++)
scanf("%d", &x[i]);
}
int produs(int *a, int* b, size_t s)
{
int produs = 0;
for(int i = 0; i < s; i++)
produs = a[i] * b[i] + produs;
return produs;
}
int main()
{
int n;
scanf("%d",&n);
int* a = calloc(n, sizeof(int));
int* b = calloc(n, sizeof(int));
citire(a, n);
citire(b, n);
// produs() returns int, not int*
int p = produs(a,b,n);
printf("%d", p);
return 0;
}
You're using pointers in places where pointers don't belong. In C passing a pointer to a single value means "this is mutable", but you don't change those values, so no pointer is necessary nor advised.
Try and use size_t as the "size of thing" type. That's what's used throughout C and it's an unsigned value as negative indexes or array lengths don't make any sense.

How am i using wrongly the void expression?

I'm newbie in C and wanted to create a function that receives one integer n and one array V, and check if my array contains the values of 1 to n.
This is my actual code:
#include <stdio.h>
void checkArray(int n, int* V);
void checkArray(int n, int* V){
int remain = n;
size_t length = sizeof V / sizeof V[0];
for(int i = 0; i<length;i++){
for(int j = 0; j<length;j++){
if(V[j] == remain){
remain--;
}
}
}
if(remain == 0)
printf("It's Latin");
printf("Not Latin");
}
int main(){
int n;
scanf("%d", &n);
int V[] = {1,2,3,4,5,6,7,8};
printf(checkArray(n, V));
}
I'm getting the error at my printf, where it says invalid use of void expression.
Your checkArray() function returns nothing (which is what void means) and you are trying to print that 'nothing' which is obviously impossible. Your checkArray() function already prints the result so you don't need to print anything in main().
It's seems though that you are missing else before printf("Not Latin") and your length variable is also incorrect. The V parameter of your checkArray() function is just a pointer (like a reference) to array and it doesn't hold any size information, you'll have to pass size separately to your function if you want to be able to traverse the array properly.
In my view, there are two mistakes in your program.
1. You didn't put "else" condition in function definition.
2. you already print something in your functions definitions so no need to use 'printf' in main() function.
you just call that function.
and put "return 0;" in last of the main function.
To put together:
#include <stdio.h>
void checkArray(int n, int* V, size_t length);
void checkArray(int n, int* V, size_t length){
int remain = n;
for(int i = 0; i<length;i++){
for(int j = 0; j<length;j++){
if(V[j] == remain){
remain--;
}
}
}
if(remain == 0){
printf("It's Latin");
else {
printf("Not Latin");
}
}
int main(){
int n;
size_t length;
scanf("%d", &n);
int V[] = {1,2,3,4,5,6,7,8};
length = sizeof(V) / sizeof(V[0]);
checkArray(n, V, length);
return 0;
}

Pointer to Pointer array & Stack Smashing error

I need to allocate an array with a malloc and I have to read some numbers from input. This is my code:
#include <stdio.h>
#include <stdlib.h>
void read(int **array, int *array_size)
{
int *tmp;
int i;
scanf("%d", array_size);
*array=malloc(*array_size*sizeof(int));
tmp=malloc(*array_size*sizeof(int));
for(i=0;i<*array_size;i++)
{
scanf("%d", &tmp[i]);
array[i]=&tmp[i];
}
}
//DO NOT EDIT main()
int main()
{
int *array;
int array_size,i;
read(&array,&array_size);
printf("Print array:\n");
for(i=0;i<array_size;i++)
printf("%d\n", array[i]);
return 0;
}
It kinda works, but after displaying values it shows a stack smashing detected (I compiled it with GCC).
I thought the problem is that *array=malloc(*array_size*sizeof(int)), but I can't figure out how to fix it. Is there another way to allocate this array without editing main()? Thank you.
The problem is that you're indexing the wrong array. You should be writing (*array)[i], not array[i]:
void read(int **array, int *array_size)
{
int *tmp;
int i;
scanf("%d", array_size);
*array=malloc(*array_size*sizeof(int));
tmp=malloc(*array_size*sizeof(int));
for(i=0;i<*array_size;i++)
{
scanf("%d", &tmp[i]);
(*array)[i]=tmp[i];
}
}
Of course all this is very complicated - you don't need to actually have that tmp, nor do you need to malloc it. Instead you could very well do something like
void read(int **array, int *array_size) {
int i, *pos;
scanf("%d", array_size);
*array = pos = malloc(*array_size * sizeof(int));
for (i = 0; i < *array_size; i ++, pos ++) {
scanf("%d", pos);
}
}
That is we have the pointer pos to point to the current position in the array where we want to scanf the next integer. On each loop we increment the position.
Naturally, you'd want to check the return values of these scanfs and malloc; and perhaps read should have a different prototype, such as
int *read(int *array_size);
so it could return the pointer to the array directly, or NULL on error.

thread 1: EXC_BAD_ACCESS(code = 1, address = 0x7fff00000001)

I'm trying to pass an array to a function that sums up all the elements in the array, but I get a bad access error at the line sum+=a[i]; how can i fix this? Here is the code:
#import <Foundation/Foundation.h>
int sum(int*, int);
int main() {
#autoreleasepool {
int size = 0;
int a[size];
int x;
NSLog(#"Enter a size for the array ");
scanf("%i", &size);
NSLog(#"Enter %i numbers to populate the array ", size);
for (int i = 0; i < size; i++) {
scanf("%i", &a[i]);
}
x = sum(a, size);
NSLog(#"The sum of the array is %i ", x);
}
return 0;
}
int sum(int *a, int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += a[i];
}
return sum;
}
It is because your array is 0 in size. Writing / Reading from a[i] may / may not crash as it's behavior is undefined.
Instead of
int size = 0;
int a[size];
int x;
NSLog(#"Enter a size for the array ");
scanf("%i", &size);
you should do this instead:
int size = 0;
int *a;
int x;
NSLog(#"Enter a size for the array ");
scanf("%i", &size);
a = malloc(sizeof(int) * size);
By dynamically allocate the array a, your program should no longer crash.
And after we use malloc, we have to free it when we don't need it anymore. Put this before return 0;
free(a);
Hope this helps.
You've defined an array of size 0. Since an array is a block of memory, and in this case a block of "no" memory, you cannot store anything into it.
You can use malloc/free as indicated in #Owen's answer. C99 also added the ability to declare arrays on the stack (so-called VLA, Variable Length Arrays). This saves you using malloc/free but leaves you at risk of using up all your stack space. For values which you know for a fact will be constrained, a VLA might make sense:
int size;
NSLog(#"Enter a size for the array ");
scanf("%i", &size);
int arr[size];
....
Note that in C89/C90/ANSI you would not be able to do that, since the size of an array must be a compile-time constant.

Resources