Array in C containing Incorrect Values - c

The goal of this program is to add the first and last elements of an array together and set that value as the first element of an output array, and then continue moving inwards as such. All of the sums will be stored in an output array. For this program, the rules stipulate that I may only use pointers and pointer arithmetic (i.e. no subscripting, no '[]', etc.) I have gotten the program to work for arrays of length 2 as well and length 4 (as I have only implemented functionality for even-lengthed arrays) however when I try any array of length 6 or above, the program adds together incorrect values that are not in the first array.
I have already tried using two different debuggers to isolate where the problem is coming from and for the life of me I can not figure it out. I have spent a few hours looking over my notes on C and going through the code, reworking it however I can. I feel as if there is something wrong with how I am interacting between the array and the pointer variables, but I am unsure. I couldn't seem to find any questions on Stack Overflow too similar to this one (yes, I looked).
void add(int *a1, int array_size, int *a2) {
int * p;
int * temp = (a1+(array_size-1));
if (array_size % 2 == 0) {
array_size = array_size/2;
for (p = a2; p < (a2+array_size); p++) {
*p = *a1 + *temp;
printf("%d", *a1);
printf(" + %d", *temp);
a1++;
temp--;
printf(" = %d\n", *p);
}
}
}
For arrays of length 2 and 4 (again, I am only testing even numbers for now), the code works fine.
Example Output:
Enter the length of the array: 2
Enter the elements of the array: 1 2
1 + 2 = 3
The output array is: 3
Enter the length of the array: 4
Enter the elements of the array: 1 2 3 4
1 + 4 = 5
2 + 3 = 5
The output array is: 5 5
Now this is where it is going wrong.
When I do this:
Enter the length of the array: 6
Enter the elements of the array: 1 2 3 4 5 6
I expect:
1 + 6 = 7
2 + 5 = 7
3 + 4 = 7
The output array is: 7 7 7
But instead, the output is:
1 + 0 = 1
2 + 3 = 5
3 + 4 = 7
The output array is: 1 5 7
My best guess is that something went wrong with my use of pointers or perhaps pointer syntax. Any help I can get, positive or negative, would be greatly appreciated.
This is the main() function:
int main() {
int size = 0;
int out_size = 0;
int arr[size];
printf("Enter the length of the array: ");
scanf("%d", & size);
printf("\nEnter the elements of the array: ");
for (int i = 0; i < size; i++) {
scanf("%d", & arr[i]);
}
if (size % 2 == 0) {
out_size = size/2;
}
else{
out_size = ((size-1)/2) + 1;
}
int out[out_size];
//calling the add function and using the addresses of arrays + array size
add(arr, size, out);
//iterating through and printing output array which has now been
//altered by the move function
printf("\nThe output array is: ");
for (int i = 0; i < out_size; i++) {
printf("%d ", out[i]);
}
return 0;
}

You are using an array of size 0:
int main() {
int size = 0;
int out_size = 0;
int arr[size]; // <- Here is your problem
You could move the array declarations after the size reading:
int main() {
int size = 0;
int out_size = 0;
printf("Enter the length of the array: ");
scanf("%d", & size);
int arr[size];
printf("\nEnter the elements of the array: ");
for (int i = 0; i < size; i++) {
scanf("%d", & arr[i]);
}

Related

My code doesn't run the same way on different compilers

first of all, I'm just starting to learn C programming on my own so please don't be mad if I'm explaining or doing something wrong, I tried to search similar question to my problem on StackOverflow but I couldn’t find one so please if I'm doing something wrong, take it easy on me I'm only trying to learn.
I have an issue I can't understand, I wrote a sorting list program using the Insertion sort algorithm, that runs differently on different compilers.
when I enter only positive numbers everything works smoothly but if I add some negatives numbers, depending on the compiler, it sometimes works and sometimes does not work at all/ prints a weird result
#include <stdio.h>
#include <string.h>
int main()
{
// gathering sources for sorting an array:
int myArray[5];
int count = 1;
for (int arrayIndex = 0; arrayIndex < 5; arrayIndex++)
{
printf("\nEnter the #%d array element: ", count);
scanf(" %d", &myArray[arrayIndex]);
count++;
}
// calculate the last array index
int myInt = myArray[0];
int arrayLength = ((sizeof(myArray)) / (sizeof(myInt))) - 1;
// printing the unsorted array
printf("\nthe array was: ");
for (int i = 0; i <= arrayLength; i++)
{
printf(" %d ", myArray[i]);
}
// sorting the array using insertion sorting algorithm:
for (int index = 1; index <= arrayLength; index++)
{
int numberCheck = index;
while (index >= 1 && myArray[numberCheck] < myArray[numberCheck - 1])
{
// swap the places:
int temp;
temp = myArray[numberCheck];
myArray[numberCheck] = myArray[numberCheck - 1];
myArray[numberCheck - 1] = temp;
// move the next element
numberCheck--;
}
}
// printing the sorted array:
printf("\nthe sorted array is now: ");
for (int i = 0; i <= arrayLength; i++)
{
printf(" %d ", myArray[i]);
}
return 0;
}
for example if I enter (0,-2,-4,12,5)
on C Online Compiler - Programiz
I get this result :
the array was: 0 -2 -4 12 5
the sorted array is now: -4 -2 0 5 12
but if I enter the same exact code on the Vscode Zsh compiler (I'm using a MacBook and to my knowledge, I didn't change anything on the compiler settings)
I get the result :
the array was: 0 -2 -4 12 5
the sorted array is now: 5 6
I tested out your code and found a few areas where processing of array elements was going out of bounds. Some places, the value of the index was -1 and some places the value was equal to the array length value (e.g. index values that equate to myArray[5] which again is out of bounds).
Following is a copy of your code with a bit of cleanup to illustrate some usual and customary methods for processing "for" loops and processing arrays.
#include <stdio.h>
#include <string.h>
int main()
{
// gathering sources for sorting an array:
int myArray[5];
int count = 1;
for (int arrayIndex = 0; arrayIndex < 5; arrayIndex++)
{
printf("\nEnter the #%d array element: ", count);
scanf(" %d", &myArray[arrayIndex]);
count++;
}
// calculate the last array index
int myInt = myArray[0];
int arrayLength = ((sizeof(myArray)) / (sizeof(myInt))); /* Omittted the subtraction of 1 */
// printing the unsorted array
printf("\nthe array was: ");
for (int i = 0; i < arrayLength; i++) /* Set loop test to be less than array length */
{
printf(" %d ", myArray[i]);
}
// sorting the array using insertion sorting algorithm:
for (int index = 1; index < arrayLength; index++)
{
int numberCheck = index;
//while (index >= 1 && myArray[numberCheck] < myArray[numberCheck - 1]) /* This line of code was allowing numberCheck - 1 to be less than zero */
while (numberCheck > 0 && myArray[numberCheck] < myArray[numberCheck - 1]) /* Revised version of the test */
{
// swap the places:
int temp;
temp = myArray[numberCheck];
myArray[numberCheck] = myArray[numberCheck - 1];
myArray[numberCheck - 1] = temp;
// move the next element
numberCheck--;
}
}
// printing the sorted array:
printf("\nthe sorted array is now: ");
for (int i = 0; i < arrayLength; i++) /* Revised this to not go out of bounds */
{
printf(" %d ", myArray[i]);
}
printf("\n");
return 0;
}
It appears in the program that you are attempting set up for loop and range testing based on a range of "1" to "array length"; whereas, the usual range processing is from "0" to "less than array length". When I did those bits of cleanup, I was able to acquire a properly sorted array from the five values entered.
#Una:~/C_Programs/Console/Sorting/bin/Release$ ./Sorting
Enter the #1 array element: 700
Enter the #2 array element: 343
Enter the #3 array element: 2
Enter the #4 array element: 58
Enter the #5 array element: 400
Array length: 5
the array was: 700 343 2 58 400
the sorted array is now: 2 58 343 400 700
Note the comments I added to hopefully clarify bits for you. Try that out and see if it meets the spirit of your project.

Remove unnecessary value entries from multidimensional array in c?

Hi I am working with a scenario where user input multiple contiguous arrays of different lengths and I want to store these array for further use.
I am using multidimensional array for this purpose.
Here is the code :
#include <stdio.h>
int main()
{
int rows,cols;
printf("Enter the number of user input arrays ? ");
scanf("%d",&rows);
printf("Enter the maximum number of inputs in a single array ?"); //Need to remove these lines
scanf("%d", &cols); //Need to remove these lines if possible
int array[rows][cols];
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
array[i][j]=0;
}
}
for(int i=0;i<rows;i++)
{
int count;
printf("Enter the number of inputs for array %d - ", i);
scanf("%d",&count);
for(int j=0;j<count;j++)
{
scanf("%d",&array[i][j]);
}
}
//// Use array for other purpose
////printf("\n\nArray --> \n");
////for(int i=0;i<rows;i++)
////{
////for(int j=0;j<cols;j++)
////{
////printf("%d ",array[i][j]);
////}
////printf("\n");
////}
return 0;
}
Example input :
Enter the number of user input arrays ? 5
Enter the maximum number of inputs in a single array ?5
Enter the number of inputs for array 0 - 5
1 2 6 3 5
Enter the number of inputs for array 1 - 1
3
Enter the number of inputs for array 2 - 2
6 5
Enter the number of inputs for array 3 - 1
3
Enter the number of inputs for array 4 - 1
9
Array created in this case :
1 2 6 3 5
3 0 0 0 0
6 5 0 0 0
3 0 0 0 0
9 0 0 0 0
Now I have number of issues in this case :
I want to reduce the space being used by removing the unnecessary entries in the array.
I would not like to use '0' or any other integer to define an unnecessary entry as it is a valid input.
I would like to remove the line
printf("Enter the maximum number of inputs in a single array ?");
scanf("%d", &cols);
Can anyone provide me help to overcome these issues.
From the design criteria you have described:
Array with user determined number of rows.
Rows have differing lengths, also user determined.
Reduce the space being used. (space only for real inputs, no padding, or filler values.)
Array definition is created at run-time per user inputs, but is not required to change during same run-time session.
Note: One design criteria: //Need to remove these lines if possible is not included in this solution. Without a description of the desired method to instruct user, I do not know how to improve on the the user prompt method.
Jagged arrays may be what you are looking for. Following is a simple example directly from the link that incorporates dynamic memory allocation that can be adapted to the code you have already discussed:
int main()
{
int rows;
//Place you user input prompts and scans here
// User input number of Rows
int* jagged[2];//
// Allocate memory for elements in row 0
jagged[0] = malloc(sizeof(int) * 1);
// Allocate memory for elements in row 1
jagged[1] = malloc(sizeof(int) * 3);
// Array to hold the size of each row
int Size[2] = { 1, 3 }, k = 0, number = 100;
// User enters the numbers
for (int i = 0; i < 2; i++) {
int* p = jagged[i];
for (int j = 0; j < Size[k]; j++) {
*p = number++;
// move the pointer
p++;
}
k++;
}
k = 0;
// Display elements in Jagged array
for (int i = 0; i < 2; i++) {
int* p = jagged[i];
for (int j = 0; j < Size[k]; j++) {
printf("%d ", *p);
// move the pointer to the next element
p++;
}
printf("\n");
k++;
// move the pointer to the next row
jagged[i]++;
}
return 0;
}
This is the concept moved a little closer to what I think you want, adapted from the code above to accept user input similar to what your code does...
int main(int argc, char *argv[])
{
int rows = 0;
int cols = 0;
int i, j;
int number = 100;
printf("Enter the number of user input arrays ? ");
scanf("%d",&rows);
// n Rows
int* jagged[rows];
int Size[rows];//array to keep size if each array
for(i=0;i<rows;i++)
{
printf("Enter the maximum number of inputs for array[%d]: ", i);
scanf("%d", &cols); //Need to remove these lines if possible
// Allocate memory for elements in row 0
jagged[i] = malloc(sizeof(jagged[i]) * cols);
Size[i] = cols;//set size of nth array
}
// User enters the numbers (This is spoofed. You will need to code per comment below.
for (i = 0; i < rows; i++) {
int* p = jagged[i];
for (j = 0; j < Size[i]; j++) {
*p = number++; //Note, this is spoofing user input .
//actual user input would be done exactly as above
//with printf prompts and scans for value
// move the pointer
p++;
}
}
// Display elements in Jagged array
for (i = 0; i < rows; i++) {
int* p = jagged[i];
for (int j = 0; j < Size[i]; j++) {
printf("%d ", *p);
// move the pointer to the next element
p++;
}
printf("\n");
// move the pointer to the next row
jagged[i]++;
}
return 0;
}

reverse an array with recursion

When I try to run this it asks me to input 11 numbers instead of 10 with is really weird then it out puts like an even weirder result please help.
void function(int array[],int length,int start)
{
if (length<start)
{
return;
}
int temp=array[start];
array[start]=array[length];
array[length]=temp;
function(array,length-1,start+1);
}
int main()
{
int array[10],num=0,num2=10;
printf("enter the array:\n");
for (int i =0; i<num2; i++)
{
scanf("%d\n",&array[i]);
}
function(array,num2,num);
for (int t = 0; t<num2; t++)
{
printf("%d\n",array[t]);
}
}
then this is the out put for the array 1,2 ... 10,11
enter the array:
1
2
3
4
5
6
7
8
9
10
11
return
214696143
10
9
8
7
6
5
4
3
2
(lldb)
please help
The last index of an array with size 10 is actually 9. So this line:
function(array,num2,num);
Should be:
function(array,num2-1,num);
Also, your use of scanf is incorrect. Eliminate the \n character. Read more about scanf here: http://www.cplusplus.com/reference/cstdio/scanf/
I corrected your code and tested it here: https://onlinegdb.com/B1Yy4yBqN
Try this:
#include <stdio.h>
void function(int array[],int start, int end)
{
if (start < end)
{
int temp;
temp = array[start];
array[start] = array[end];
array[end] = temp;
function(array, start+1, end-1);
}
}
int main()
{
int array[10],num=0,num2=10;
printf("enter the array:\n");
for (int i =0; i<num2; i++)
{
scanf("%d",&array[i]);
}
function(array,num,num2 - 1);
for (int t = 0; t<num2; t++)
{
printf("%d\n",array[t]);
}
}
Note that in C, the array starts from 0. The last index is 9 not 10. You need to access to the last element using length - 1 instead of length

Making an array smaller with realloc, losing first element

I've been trying to make an example program using calloc and realloc and I've come across an issue where, when I make an array of integers smaller, it seems to remove the first element instead of the last one.
int *m = (int*)calloc(2, sizeof(int));
*m = 1;
*(m+1) = 2;
printf("\tInt 1: %d\n", m[0]);
printf("\tInt 2: %d\n\n", *(m+1));
// REALLOC
printf("How many elements the array have? ");
scanf("%d", &num);
*m = (int *)realloc(m, num * sizeof(int));
printf("ARRAY NOW HAS %d PLACES\n\n\t", num);
for(i = 0; i < num; i++) {
m[i] = i + 1;
printf("%d ", m[i]);
}
// DELETING MEMBERS OF AN ARRAY
while((d < 0) || (d > num)) {
printf("\n\nChoose which position of the previous array should be deleted (0 = first): ");
scanf("%d", &d);
}
printf("\nUPDATED ARRAY:\n\n");
for(i = d; i < num - 1; i++) {
m[i] = m[i + 1];
}
*m = (int *)realloc(m, (num - 1)*sizeof(int));
num--;
for(i = 0; i < num; i++) {
printf("%d ", m[i]);
}
An example of the program output would be:
Int 1: 1
Int 2: 2
How many elements the array have? 17
ARRAY NOW HAS 17 PLACES
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Choose which position of the previous array should be deleted (0 = first): 6
UPDATED ARRAY:
10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17
And if I include the last member of the array that should have been deleted (in this case m[16]) it shows:
10620272 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17 17
Of course, I'm not entirely sure what's happening but it seems like it's just removing the value of m[0]?
Thanks in advance for any help!
The reason the initial value gets modified is that you are assigning it:
*m = (int *)realloc(m, num * sizeof(int));
should be
m = realloc(m, num * sizeof(int));
Your code should also produce a warning, telling you that an assignment of a pointer to an array element containing ints is invalid. Fixing this warning should have fixed your problem.
Note that an assignment of the form
m = realloc(m, ...);
where m is used on both sides of realloc is inherently unsafe, because realloc could potentially return NULL - for example, when there is not enough memory to allocate. Blind assignment to m would render the old value of m inaccessible, preventing proper deallocation. In production you should assign realloc's result to a temporary, then check it for NULL, and only then assign the result back to m.
In addition to #dasblinkenlight good answer, when reducing the allocation size and the re-allocation fails (a rare event), code can simple continue with the original pointer.
Suggested re-write, assuming num > 0:
// *m = (int *)realloc(m, num * sizeof(int));
void *t = realloc(m, sizeof *m * num);
if (t) {
m = t;
}

Appending a value to the end of a dynamic array

Well I have been studying a little C this winter break and in my adventures I stumbled upon an issue with a Dynamic Array.
It's a fairly simple program really. What I am trying to do is to create an array that holds the numbers of the Fibonacci series. Here is the code:
#include <stdio.h>
#include <stdlib.h>
int dynamic_arry_append(int* arry, int* number, int* size);
int main() {
int i, n, size = 3, *arry = NULL, fibarr[size];
printf("Dynamic array, Fibonacci series. \n");
printf("Capture upto element: ");
scanf("%d", &n);
i = 0;
// passing the first elements
fibarr[0] = 0;
fibarr[1] = 1;
fibarr[2] = 1;
while ( i < n ) {
printf("**%d\n",fibarr[0]);
dynamic_arry_append( arry, &fibarr[0], &size );
fibarr[0] = fibarr[1];
fibarr[1] = fibarr[2];
fibarr[2] = fibarr[1] + fibarr[0];
i++;
}
for ( i = 0 ; i < size ; i++)
printf("Element %d of the array: %d.\n", i, arry[i]);
return 0;
}
int dynamic_arry_append(int* arry, int* number, int* size) {
int i;
int bacon = *size; // first name i thought of
bacon++;
int *new_addr = realloc(arry, bacon * sizeof(int));
if( new_addr != NULL ) {
arry = new_addr;
arry[bacon-1] = *number;
// printf for easier debugging, or so i thought
for ( i = 0 ; i < bacon ; i++ )
printf("%d\t%d\n", i+1, arry[i]);
printf("\n");
*size = bacon;
} else {
printf("Error (re)allocating memory.");
exit (1);
}
return 0;
}
At least in my mind this works. However, in practice I get funny results:
Dynamic array, Fibonacci series.
Capture upto element: 5
**0 // next fibonacci number
1 5256368
2 5246872
3 1176530273
4 0
**1
1 5256368
2 5246872
3 1768053847
4 977484654
5 1
**1
1 5256368
2 5246872
3 1551066476
4 1919117645
5 1718580079
6 1
**2
1 5256368
2 5246872
3 977484645
4 1852397404
5 1937207140
6 1937339228
7 2
**3
1 5256368
2 5246872
3 1551071087
4 1953724755
5 842231141
6 1700943708
7 977484653
8 3
/* Code::Blocks output */
Process returned -1073741819 (0xC0000005) execution time : 17.886 s
Press any key to continue.
I am really baffled by this error, and after searching around I found no solution...Can anyone help? Thank you very much.
#include <stdio.h>
#include <stdlib.h>
int * dynamic_array_append(int * array, int size);
int main() {
int i, n, size=0, *array = NULL;
printf("Dynamic array, Fibonacci series. \n");
printf("Capture upto element: ");
scanf("%d", &n);
for (i=0 ; i<n ; i++)
array = dynamic_array_append(array, i);
for (i=0 ; i<n ; i++)
printf("array[%d] = %d\n", i, array[i]);
return 0;
}
int * dynamic_array_append(int * array, int size)
{
int i;
int n1, n2;
int new_size = size + 1;
int * new_addr = (int *) realloc(array, new_size * (int)sizeof(int));
if (new_addr == NULL) {
printf("ERROR: unable to realloc memory \n");
return NULL;
}
if (size == 0 || size == 1) {
new_addr[size] = size;
return new_addr;
}
n1 = new_addr[size-1];
n2 = new_addr[size];
new_addr[new_size-1] = new_addr[new_size-2] + new_addr[new_size-3];
return new_addr;
}
/*
Output:
Dynamic array, Fibonacci series.
Capture upto element: 10
array[0] = 0
array[1] = 1
array[2] = 1
array[3] = 2
array[4] = 3
array[5] = 5
array[6] = 8
array[7] = 13
array[8] = 21
array[9] = 34
*/
Points to note:
The newly (re)allocated array should be returned back to main and stored in a pointer-to-int (or) pass pointer-to-pointer-to-int and update it accordingly once after reallocing
The fibarr is not needed. It doesn't solve any problem.
You don't have to pass the size and the number. Just send the size and it will pick the n-1 and n-2 to calculate n.
This is considered to be highly inefficient. Because if you know the n then you can allocate memory for n integers in one shot and calculate the fib series.
The problem may be that the arry pointer variable is passed by value to the function dynamic_arry_append. That means, that changes that you make to the arry variable within that function will not be reflected by any variables outside of that function. For example:
int *a = NULL;
someFunc(a);
// a will still be NULL here no matter what someFunc does to it.
You should declare your fibarr as a pointer (so name it differently) not an array. And you should pass to your dynamic_arry_append the address of that pointer, like &fibarr. And you should initialize fibarr in your main with calloc. At last you should dynamically update (and keep, and pass) the size of the allocated array.
You are not returning the new address of the array... and you are reading/writing not your memory. Run the program with all error messages under debugger and you'll see the problem is in this line:
dynamic_arry_append( arry, &fibarr[0], &size );

Resources