Function to check all elements of an array - c

I want to make a function to check all elements of an array. But how to pass an array as parameter of a function correctly? I've tried to pass a pointer but it doesn't work, compiler don't even want to compile that code. What am I doing wrong? Please help!
#include <stdio.h>
#define N 10
int iseven(int *A); // prototype
int main(void)
{
int i;
int A[N]; // array to check
for (i = 0; i < N; i++)
scanf("%d", &A[i]);
i = iseven(*A);
if (i == 1)
printf("All numbers are even!\t\n");
else
printf("Not all numbers are even!\t\n");
return 0;
}
int iseven(int *A)
{
int i;
int flag = 1;
for (i = 0; i < N; i++)
if (((A[i] % 2) == 0) && (A[i] >= 2))
continue;
else
{
flag = 0;
break;
}
return flag;
}
gcc array.c -o array.exe
array.c: In function 'main':
array.c:16:14: warning: passing argument 1 of 'iseven' makes pointer from integer without a cast [-Wint-conversion]
i = iseven(*A);
^
array.c:5:5: note: expected 'int *' but argument is of type 'int'
int iseven(int *A); // array to check
^

You need to call the function in the form
i = iseven(A);
Using i = iseven(*A); means that you are dereferencing the value at address A and passing it, which effectively means you are passing the first element of the array to the function.
This is the reason the compiler complains that the function receives an int when it was expecting an int*

Related

question about two sum leetcode problem: brute force approach in C

I dont understand some small actions that has taken in this code, for example
i) why do we need to do &rs, why cant we just write
int returnSize;
p = twoSum(a, sizeof(a)/sizeof(a[0]), target, int*returnSize);
if(returnSize == 0)
instead of &rs... what is wrong with doing this?
i ran the code here:
#include <stdio.h>
#include <stdlib.h>
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int i, j;
int* ret_arr = (int*)malloc(2*sizeof(int));
if(ret_arr == NULL){
// *returnSize = 0;
returnSize = 0;
return NULL;
}
for(i = 0; i< numsSize; i++){
for(j = i+1; j< numsSize; j++){
if(nums[i] + nums[j] == target){
//*returnSize = 2;
returnSize = 2;
ret_arr[0] = I;
ret_arr[1] = j;
return ret_arr;
}
}
}
//*returnSize = 0;
returnSize = 0;
free(ret_arr);
return NULL;
}
int main()
{
int a[] = {2,7,11,15};
int returnSize, target = 18;
int *p = NULL;
p = twoSum(a, sizeof(a)/sizeof(a[0]), target, int*returnSize);
//if(*returnSize == 0){
if(returnSize == 0){
printf("target not found");
}else{
printf("target found at indices %d and %d/n", p[0], p[1]);
free(p);
}
return 0;
}
error result:
main.c: In function ‘twoSum’:
main.c:34:28: warning: assignment to ‘int *’ from ‘int’ makes
pointer from integer without a cast [-Wint-conversion]
34 | returnSize = 2;
| ^
main.c: In function ‘main’:
main.c:57:48: error: expected expression before ‘int’
57 | p = twoSum(a, sizeof(a)/sizeof(a[0]), target,
int*returnSize);
| ^~~
full code: https://onlinegdb.com/7OpTpwxZy3
i dont know how this doesn't make sense to the compiler.
ii) Pointer array conceptual Q
we need to declare pointer p in line 60 because to access returned array elements (of two sum function) and print them (like they are used in line ), on screen from main. QUESTION: WHY DO WE NEED POINTER FOR TWO SUM FUNCTION WHEN WE ALREADY HAVE pointer p DECLARED IN MAIN, ITS LIKE POINTER POINTING TO A POINTER(LIKE int*a, int*p, p = a), why does the code work?
error i get if i remove "int*" in line 4(2nd pic), in front of twosum function.
main.c:28:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
28 | twoSum(int* nums, int numsSize, int target, int* returnSize){
| ^~~~~~
main.c: In function ‘twoSum’:
main.c:34:16: warning: returning ‘void *’ from a function with return type ‘int’ makes integer from pointer without a cast [-Wint-conversion]
34 | return NULL;
| ^~~~
main.c:43:24: warning: returning ‘int *’ from a function with return type ‘int’ makes integer from pointer without a cast [-Wint-conversion]
43 | return ret_arr;
| ^~~~~~~
main.c:49:12: warning: returning ‘void *’ from a function with
return type ‘int’ makes integer from pointer without a cast [-
Wint-conversion]
49 | return NULL;
| ^~~~
main.c: In function ‘main’:
main.c:60:4: warning: assignment to ‘int *’ from ‘int’ makes
pointer from integer without a cast [-Wint-conversion]
60 | p = twoSum(a, sizeof(a)/sizeof(a[0]), target, &rs);
| ^
here is the full code for reference:
#include <stdio.h>
#include <stdlib.h>
twoSum(int* nums, int numsSize, int target, int* returnSize){
int i, j;
int* ret_arr = (int*)malloc(2*sizeof(int));
if(ret_arr == NULL){
*returnSize = 0;
return NULL;
}
for(i = 0; i< numsSize; i++){
for(j = i+1; j< numsSize; j++){
if(nums[i] + nums[j] == target){
*returnSize = 2;
ret_arr[0] = I;
ret_arr[1] = j;
return ret_arr;
}
}
}
*returnSize = 0;
free(ret_arr);
return NULL;
}
int main()
{
int a[] = {2,7,11,15};
int rs, target = 18;
int *p = NULL;
p = twoSum(a, sizeof(a)/sizeof(a[0]), target, &rs);
if(rs == 0){
printf("target not found");
}else{
printf("target found at indices %d and %d/n", p[0], p[1]);
free(p);
}
return 0;
}
i hope i provided enough information to understand the question, Question might be fairly simple for experienced programmers but i am just a beginner. Also please explain in easy simple words if you can thinking you are explaining to a beginner.
writing image as texts: i am not sure what to do because in this case image seems easier that text.
i) i tried changing the code as shown below in main function as well as in twosum function.
int returnSize;
p = twoSum(a, sizeof(a)/sizeof(a[0]), target, int*returnSize);
if(returnSize == 0)
ii) i have tried removing int* in line 4(2nd pic), in front of twosum function but i got an error shown here:
There seems to be a basic misunderstanding of what pointers are, how they works and why are used in the posted program.
The function twoSum is trying to find the two elements in an array whose sum equals a given target. The author of this snippet made the following design choices:
// The function returns a POINTER to some memory, allocated in the free store,
// where the two indeces will be stored, or NULL if no elements satisfy the constraint.
int*
twoSum( int* nums, int numsSize // The array is passed as pointer to its first
// element and size (number of elements)
, int target
, int* returnSize ) // This POINTER is used to "return" the size
// of the memory allocated in this function
// to the caller. This may be referred to as
// an "out parameter", it allows the function
// to change the value of a variable stored elsewhere.
{
int i, j;
int* ret_arr = (int*)malloc(2*sizeof(int));
if(ret_arr == NULL){
*returnSize = 0;
// ^ The pointer must be DEREFERENCED to access the value of the pointee.
return NULL;
}
/* [...] */
}
int main()
{
int a[] = {2,7,11,15};
int returnSize, target = 18;
//^^^^^^^^^^^^ This variable is declared as an int.
int *p = NULL;
p = twoSum(a, sizeof(a)/sizeof(a[0]), target, &returnSize);
// We need to pass its ADDRESS here ^^^^^^^^^^^
// because this function is expecting a POINTER to int.
if( returnSize == 0){
// ^^^^^^^^^^ Beeing an int, it must be used as an int value.
printf("target not found");
} else {
printf("target found at indices %d and %d/n", p[0], p[1]);
free(p); // <- Correct. The caller has this responsability.
}
return 0;
}
To answer the first point, it needs the & because it needs to take the address of the variable returnSize declared in main as an int. That address is passed to the function where it is used to initialize the local variable returnSize, which is declared in the signature of the function as a parameter of type int *, a pointer. Please note that those are two different objects, in different scopes, with different lifetimes and different type.
The call can't be written as
p = twoSum(a, sizeof(a)/sizeof(a[0]), target, int*returnSize);
// ^^^^ Syntax error, this isn't a declaration
why do we need pointer for twoSum function when we already have poiner p declared in main?
I'm not sure what the OP's doubts are here. The variable declared in main needs to be assigned a meaningful value, so it uses the value returned by the function. Inside twoSum, a variable of type pointer is needed to allocate the required memory and that is returned to main.
This isn't the only way to accoplish this task, in fact we might prefer to not allocate any memeory inside the function and pass an address instead:
#include <stdio.h>
#include <stdlib.h>
// If there exist two elements whose sum equals the 'target', the function returns 1
// and the indices of these elements are stored in the array 'indices'.
// Otherwise, the function returns 0 and doesn't modify 'indices'.
int
find_indices_of_sum( size_t n, int const* arr
, int target
, int *indices )
{
for(size_t i = 0; i < n; ++i)
{
for(size_t j = i + 1; j < n; ++j)
{
if( arr[i] + arr[j] == target )
{
indices[0] = i;
indices[1] = j;
return 1;
}
}
}
return 0;
}
int main(void)
{
int a[] = {2, 7, 11, 15};
size_t a_size = sizeof a / sizeof *a;
int target = 18;
// Declares the array in main.
int indices[2];
if ( find_indices_of_sum(a_size, a, target, indices) )
{ // Pass the address of its first element ^^^^^^^, the size is known (2).
printf("Target found at indices %d and %d\n", indices[0], indices[1]);
// ^^
// No need to free anything. 'indices' has automatic storage duration.
}
else
{
puts("Target not found");
}
return 0;
}
We can also directly return a struct with all the needed informations from the function, without using any "out parameter".
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct idx_pair
{
size_t first, second;
};
static inline bool is_valid(struct idx_pair p)
{
return p.first != p.second;
}
// The function returns both the indices wrapped in a single struct.
struct idx_pair
find_inidces_of_sum( size_t n, int const *arr
, int target )
{
for(size_t i = 0; i < n; ++i)
{
for( size_t j = i + 1; j < n; ++j)
{
if( arr[i] + arr[j] == target )
{
return (struct idx_pair){ .first = i, .second = j };
// ^^^^^^^^^^^^^^^^^ This is not a cast, it's a
// compound literal with designated initializers.
}
}
}
return (struct idx_pair){ .first = 0, .second = 0 };
}
int main(void)
{
int a[] = {2, 7, 11, 15};
size_t a_size = sizeof a / sizeof *a;
int target = 18;
struct idx_pair solution = find_indices_of_sum(a_size, a, target);
if ( is_valid(solution) )
{
printf("Target found at indices %d and %d\n", solution.first, solution.second);
}
else
{
puts("Target not found");
}
return 0;
}
Note though, that your compiler might not be able to optimize out all the copies and, even if the involved structure isn't that big, the generated assembly might be not optimal on some hardware.

Implicit declaration C

I wish to get my code cleaner, the code can compile, but unfortunately there are still some
stuff showing minor problem about this following "error message"
how can I solve this ?
#include <stdlib.h>
#include <stdio.h>
int main(){
int arr0[] = {1,2,3,4,5};
int arr1[] = {2,2,2,2,2};
int arr2[] = {1,4,2,4,4};
int sizeArr0 = sizeof(arr0);
int sizeArr1 = sizeof(arr1);
int sizeArr2 = sizeof(arr2);
parseArray(arr0[0], sizeArr0);
parseArray(arr1[0], sizeArr1);
parseArray(arr2[0], sizeArr2);
}
int parseArray(int ch[], int sizeValue){
int sum;
for(int x = 0; x < ch; x++){
int ch[x];
if(x == 5){
sum += 5;
}
if (sum == 15){
return sum;
}
}
}
warning: implicit declaration of function ‘parseArray’ [-Wimplicit-function-declaration]
17 | parseArray(arr0[0], sizeArr0);
| ^~~~~~~~~~
test.c: In function ‘parseArray’:
test.c:30:22: warning: comparison between pointer and integer
30 | for(int x = 0; x < ch; x++){
You need to have a function definition or prototype before the function which calls it
int parseArray(int ch[], size_t sizeValue);
int main()
{
/* ... */
for(int x = 0; x < ch; x++){ makes no sense and I believe that an typo.
for(size_t x = 0; x < sizeValue; x++){
int sizeArr0 = sizeof(arr0); is giving you the size of the array in char not in element types. You need to divide it by the size of the elements. It should also have different type (size_t) size_t sizeArr0 = sizeof(arr0) / sizeof(arr0[0]);
All local function variables have to be initialized as they are not zeroed as global variables. int sum = 0;
You pass the first element to the array not the reference to the array parseArray(arr0, sizeArr0); or parseArray(&arr0[0], sizeArr0);

C code involving malloc for dynamic allocation of 2D array crashes after compiling

I am trying to allocate the row dimension of an array (a) to the size of a user input value. Here is the code I have:
#include <stdio.h>
#include <stdlib.h>
void FreeArray(int **arry, int N);
int main() {
int **a;
int **b;
int N_a;
int N;
if (a != NULL) {
FreeArray(a, N);
}
if (b != NULL) {
FreeArray(b, N);
}
do {
printf("Enter the size of the NxN array:\n");
scanf("%d", &N);
if (N < 2) {
printf("Error, enter correct size.\n");
}
} while (N < 2);
N_a = N;
int errorInAlloc = 0;
a = (int**)malloc(N_a * sizeof(int*));
if (a != NULL) {
errorInAlloc = 1;
}
return 0;
}
void FreeArray(int **arr, int N) {
int i;
if (arr == NULL)
return;
if (arr != NULL) {
for (i = 0; i < N; i++) {
if (arr[i] != NULL)
free(arr[i]);
}
free(arr);
}
}
The FreeArray function was provided to us, so I know it is correct. There is other code included in this, but I omitted is since it is just a menu. When I comment out a = (int**) malloc(N_a * sizeof(int*)); the program compiles and runs without crashing or problems. When I include this line, the program compiles, but when I put a number greater than or equal to 2, it crashes. I have also tried a = malloc(N_a * sizeof(int*)); and a = (int**)malloc(N * sizeof(int*)); AND a = malloc(N * sizeof(int*)); but all do the same thing.
I have been coding and running the program in Code::Blocks, but even when I compile it through the command prompt, it still crashes.
I have a hard time with arrays on a good day, so dynamically allocating arrays is so confusing to me, any help is greatly appreciated!
You have multiple errors in your program:
variables a and b are uninitialized, comparing them to NULL is meaningless and passing them to FreeArray has undefined behavior.
given how the FreeArray function is written, allocation must be performed in 2 steps:
allocate an array of of pointers, which you do.
initialize each element of the array with the address of an allocated array of int. which you don't.
Here is how a function AllocArray would be written:
int **AllocArray(int N) {
int i;
int **arr = calloc(sizeof(*arr), N);
if (arr != NULL) {
for (i = 0; i < N; i++) {
arr[i] = calloc(sizeof(*arr[i]), N);
if (arr[i] == NULL) {
/* allocation failed: free allocated portion and return NULL */
while (i-- > 0) {
free(arr[i]);
}
free(arr);
return NULL;
}
}
}
return arr;
}
Note that the FreeArray function can be simplified this way:
void FreeArray(int **arr, int N) {
int i;
if (arr != NULL) {
for (i = 0; i < N; i++) {
free(arr[i]);
}
free(arr);
}
}
It is OK to pass a null pointer to free(), and a single test on arr is sufficient.
First problem is that you free an unallocated pointer:
if(a != NULL)
{
FreeArray(a, N);
}
You've never allocated memory for a, so when you try to access to a position of the vector, it generates a segmetation fault (same occurs with b). If you want to make sure that your pointer is NULL, just use a = NULL;. This will fix your problem.
There is another logical problem:
if(a != NULL)
{
errorInAlloc = 1;
}
You return an error in allocation if a differs from NULL. You should return an error if a is NULL wich means that an error occurs in the memory allocation.
Here's what gcc reported when your code was compiled with more warnings.
gcc -o xx xx.c -Wall -Wextra -pedantic -std=c99 -O2 -Wmissing-declarations -Wmissing-prototypes -Wconversion
xx.c: In function ‘main’:
xx.c:26:26: warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
a = (int **) malloc(N_a * sizeof(int *));
^
xx.c:25:6: warning: variable ‘errorInAlloc’ set but not used [-Wunused-but-set-variable]
int errorInAlloc = 0;
^
xx.c:10:5: warning: ‘a’ is used uninitialized in this function [-Wuninitialized]
if (a != NULL) {
^
xx.c:13:5: warning: ‘b’ is used uninitialized in this function [-Wuninitialized]
if (b != NULL) {
^
xx.c:11:3: warning: ‘N’ may be used uninitialized in this function [-Wmaybe-uninitialized]
FreeArray(a, N);
^
The formatting is a little bit off. The point is crystal clear: Let your compiler help you locate errors.

C: adding elements to an array

I'm trying to test a program that creates an array with 0 elements in it, then adds elements to it (reallocating memory each time), and then printing out the elements. But, I keep getting errors when I try to run it.
int main(int argc, const char * argv[]) {
int num = 0;
int n = 10;
int **array = malloc(0);
for (int i = 0; i < n; ++i)
{
++num;
array = realloc(array, num * sizeof(int*));
array[num-1] = &i;
}
for (int j = 0; j < n; ++j)
{
printf("%d", &array[j]); // error 1
}
return 0;
}
I'm sorry I didn't include the errors with the original post. I think I fixed one of them. Here is the other:
Error 1: Format specifies type 'int' but the argument has type 'int *'
This answer is based on the assumption that you are printing a simple array, since you don't show what output you expect. You are using one more step of indirection than you need, and too many variables. Take note that indexing is different from length (often by 1).
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i, n = 10;
int *array = NULL; // no need for double star, or fake allocation
for (i = 0; i < n; ++i)
{
array = realloc(array, (i + 1) * sizeof(int)); // remove the *, add 1 for num elements
array[i] = i;
}
for (i = 0; i < n; ++i)
{
printf("%d", array[i]); // remove the &
}
free(array); // don't forget this
return 0;
}
Program output:
0123456789
In practice, you should assign the result of realloc to another pointer variable, check it's ok, and then replace the original pointer var.
printf("%d", &array[j]); // error 1
The & is the address operator. So it is making something a pointer. Your array is already an array of pointers to integer.
By using the & you are trying to print the address of the integer pointer itself.
Try using * instead of &. * means that you want to print the value of the integer pointer.
printf("%d", *array[j]); // error 1

How to return an array from a function with pointers

i'm trying to figure out how to return an array from a function in the main().
I'm using C language.
Here is my code.
#include <stdio.h>
int *initArray(int n){
int i;
int *array[n];
for(i = 0; i < n; i++){
array[i] = i*2;
}
return array;
}
main(){
int i, n = 5;
int *array[n];
array[n] = initArray(n);
printf("Here is the array: ");
for(i = 0; i < n; i++){
printf("%d ", array[i]);
}
printf("\n\n");
}
And this is the errors the console gives me:
2.c: In function ‘initArray’:
2.c:8:13: warning: assignment makes pointer from integer without a cast [enabled by default]
array[i] = i*2;
^
2.c:11:3: warning: return from incompatible pointer type [enabled by default]
return array;
^
2.c:11:3: warning: function returns address of local variable [-Wreturn-local-addr]
2.c: In function ‘main’:
2.c:23:4: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("%d ", array[i]);
^
It's impossible!
I hate being a noob :(
If you could help, with explanations, I would appreciate! :D
Edit: iharob's answer is better than mine. Check his answer first.
Edit #2: I'm going to try to explain why your code is wrong
Consider the 2nd line of main() in your question:
int *array[n];
Let's try to read it backwards.
[n]
says we have an array that contains n elements. We don't know what type those elements are and what the name of the array is, but we know we have an array of size n.
array[n]
says your array is called array.
* array[n]
says you have a pointer to an array. The array that is being pointed to is called 'array' and has a size of n.
int * array[n];
says you have a pointer to an integer array called 'array' of size n.
At this point, you're 3/4 way to making a 2d array, since 2d arrays consist of a list of pointers to arrays. You don't want that.
Instead, what you need is:
int * array;
At this point, we need to examine your function, initArray:
int *initArray(int n){
int i;
int *array[n];
for(i = 0; i < n; i++){
array[i] = i*2;
}
return array;
}
The second line of initArray has the same mistake as the second line of main. Make it
int * array;
Now, here comes the part that's harder to explain.
int * array;
doesn't allocate space for an array. At this point, it's a humble pointer. So, how do we allocate space for an array? We use malloc()
int * array = malloc(sizeof(int));
allocates space for only one integer value. At this point, it's more a variable than an array:
[0]
int * array = malloc(sizeof(int) * n);
allocates space for n integer variables, making it an array:
e.g. n = 5:
[0][0][0][0][0]
Note:The values in the real array are probably garbage values, because malloc doesn't zero out the memory, unlike calloc. The 0s are there for simplicity.
However, malloc doesnt always work, which is why you need to check it's return value:
(malloc will make array = NULL if it isn't successful)
if (array == NULL)
return NULL;
You then need to check the value of initArray.
#include <stdio.h>
#include <stdlib.h>
int *initArray(int n){
int i;
int *array = malloc(sizeof(int) * n);
if (array == NULL)
return NULL;
for(i = 0; i < n; i++){
array[i] = i*2;
}
return array;
}
int main(){
int i, n = 5;
int *array = initArray(n);
if (array == NULL)
return 1;
printf("Here is the array: ");
for(i = 0; i < n; i++){
printf("%d ", array[i]);
}
free(array);
printf("\n\n");
return 0;
}
You can't just return an array like that. You need to make a dynamically allocated array in order to do that. Also, why did you use a 2d array anyway?
int array[5];
is basically (not completely) the same as:
int * array = malloc(sizeof(int) * 5);
The latter is a bit more flexible in that you can resize the memory that was allocated with malloc and you can return pointers from functions, like what the code I posted does.
Beware, though, because dynamic memory allocation is something you don't wanna get into if you're not ready for tons of pain and debugging :)
Also, free() anything that has been malloc'd after you're done using it and you should always check the return value for malloc() before using a pointer that has been allocated with it.
Thanks to iharob for reminding me to include this in the answer
Do you want to initialize the array? You can try it like this.
#include <stdio.h>
void initArray(int *p,int n)
{
int i;
for(i = 0; i < n; i++)
{
*(p+i) = i*2;
}
}
void main(void)
{
int i, n = 5;
int array[n];
initArray(array,n);
printf("Here is the array: ");
for(i = 0; i < n; i++)
{
printf("%d ", array[i]);
}
printf("\n\n");
}
If you don't want to get in trouble learning malloc and dynamic memory allocation you can try this
#include <stdio.h>
void initArray(int n, int array[n]) {
int i;
for (i = 0 ; i < n ; i++) {
array[i] = i * 2;
}
}
int main() { /* main should return int */
int i, n = 5;
int array[n];
initArray(n, array);
printf("Here is the array: ");
for(i = 0 ; i < n ; i++) {
printf("%d ", array[i]);
}
printf("\n\n");
return 0;
}
as you see, you don't need to return the array, if you declare it in main(), and pass it to the function you can just modify the values directly in the function.
If you want to use pointers, then
#include <stdio.h>
int *initArray(int n) {
int i;
int *array;
array = malloc(n * sizeof(*array));
if (array == NULL) /* you should always check malloc success */
return NULL;
for (i = 0 ; i < n ; i++) {
array[i] = i * 2;
}
return array;
}
int main() { /* main should return int */
int i, n = 5;
int *array;
array = initArray(n);
if (array == NULL) /* if null is returned, you can't dereference the pointer */
return -1;
printf("Here is the array: ");
for(i = 0 ; i < n ; i++) {
printf("%d ", array[i]);
}
free(array); /* you sould free the malloced pointer or you will have a memory leak */
printf("\n\n");
return 0;
}

Resources