Reputation: 21
I am trying to assign values to elements in dynamic array, but can't find solution. There are many videos showing how it works if value is entered by the user via scanf, but here it's not the case. I really tried to find info here and there and solve it myself so any help will be highly appreciated. Here is my code:
//Program co convert decimal number to binary and count zeros
int main()
{
int decimalNum;
int *binaryNum;
int zeroCounter = 0;
int i = 0;
int sizeOfArray;
int decimalNumCopied;
printf("Please enter a number from 0 to 255: ");
scanf("%d", &decimalNum);
decimalNumCopied = decimalNum;
while(decimalNum != 0)//checking number of bits;
{
decimalNum = decimalNum / 2;
i++;
}
sizeOfArray = i;
//Trying to allocate just enough memory
binaryNum = (int*)malloc(sizeOfArray * sizeof(int));
while(decimalNumCopied != 0)
{
/*At next step I am trying to assign values to each element of the
array and it doesn't work
*/
binaryNum[i] = decimalNumCopied % 2;
decimalNumCopied = decimalNumCopied / 2;
i--;
}
for(i = 0; i <= sizeOfArray; i++)
{
printf("%d", binaryNum[i]);
if(binaryNum[i]== 0){zeroCounter++;}
}
printf("\nThere are %d zeroes", zeroCounter);
free(binaryNum);
return 0;
}
Upvotes: 1
Views: 5510
Reputation: 664
I felt this was a useful program so incorporating the answer by dbush and others, here it is fixed, valgrind checks good, with some user input error handling, some stylistic changes, and alternatively also accepts input from the command line.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char**argv) {
int decimalNum;
int *binaryNum;
int zeroCounter = 0;
int i = 0;
int sizeOfArray;
int decimalNumCopied;
if (argc == 2) {
decimalNum = atoi(argv[1]);
}
if(argc == 1 || decimalNum < 0 || decimalNum > 255) {
printf("Please enter a number from 0 to 255: ");
scanf("%d", &decimalNum);
while (decimalNum < 0 || decimalNum > 255) {
printf("Program is expecting an int from 0 to 255 inclusive\n"
"Please enter a number from 0 to 255: ");
scanf("%d", &decimalNum);
}
}
decimalNumCopied = decimalNum;
while (decimalNum != 0) {
decimalNum /= 2;
i++;
}
sizeOfArray = i;
binaryNum = malloc(sizeOfArray * sizeof(int));
i--;
while (decimalNumCopied != 0) {
binaryNum[i] = decimalNumCopied % 2;
decimalNumCopied /= 2;
i--;
}
for (i = 0; i < sizeOfArray; i++) {
printf("%d", binaryNum[i]);
if (binaryNum[i] == 0) { zeroCounter++; }
}
printf("\nThere are %d zeroes\n", zeroCounter);
free(binaryNum);
return 0;
}
Upvotes: 0
Reputation: 223972
There are two errors here.
First, when you start assigning values to the array i
is equal to the number of elements in the array. Since arrays in C have indexes from 0 to n-1, where n is the length, you're writing one element past the end of the array. Doing so invokes undefined behavior, which in this case (lucky for you) manifests in a crash.
You need to decrement i
once before entering the loop to start writing at the proper offset.
i--;
while(decimalNumCopied != 0)
{
...
The second issue is with the printing. Your for
loop starts at 0 (as it should), but stops when i <= sizeOfArray
is no longer true. So on the last iteration i
is equal to sizeOfArray
, so read one element past the end of the array. Again, this invokes undefined behavior.
Change the condition to <
to prevent this:
for(i = 0; i < sizeOfArray; i++)
Upvotes: 3
Reputation: 399843
Your first assignment is outside the bounds of the array. This gives you undefined behavior.
Remember that arrays are indexed from zero, so if i
is the length of the array it is not a valid index (it's one beyond the last valid index).
Upvotes: 4