C Pointer: char to binary value - c

#include <stdio.h>
#include <string.h>
int * bin(char a);
int main(void){
char a='a';
int k=0;
int *binary;
binary=bin(a);
for(k=0; k<8; k++){
printf("%d", *binary++);
printf("\n");
}
return 0;
}
int *bin(char a){
int i=0;
int *arr;
int output[8];
char c=a;
for (i = 0; i <8 ; ++i) {
output[8-i-1] = (a >> i) & 1;
}
arr=&output[0];
// for (i = 0; i <8 ; ++i) {
// printf("%d", output[i]);
// }
// printf("\n");
return arr;
}
The ouptut should be the binary value of the char 'a'which is:
0
1
1
0
0
0
0
1
but i got this instead:
0
-1216804320
-1218095335
-1216804320
10
-1076423592
-1218208721
-1216804320
Is this a pointer problem?
How do i fix it so it would print the right answer? thx!!

You're returning a pointer to a local variable (arr), whose contents are no longer valid when the function returns. Use malloc instead:
int main(void){
...
int *arr = bin(a);
...
free(arr);
return 0;
}
int *bin(char a){
int *arr = malloc(8 * sizeof int);
...
return arr;
}

First error I can notice is Scope problem, that you are returning address of local variable output[8];
arr=&output[0];
return arr;
That is wrong, scope of output[] is inside bin() function only.
You should allocate memory for output[] dynamically if you want to access it outside bin() function, like:
int *output = calloc(8, sizeof(int));
even you don't need extra variable just return output from bin()
I have corrected you code like below without much change:
int *bin(char a){
int i=0;
int *output = calloc(8, sizeof(int));
for (i = 0; i <8 ; ++i) {
output[8-i-1] = (a >> i) & 1;
}
return output;
}
Notice removed unused variables c and arr
additionally, don't forgot to free dynamically allocated memory explicitly:
Second (Notice) be aware of Memory Clobbering Error because you are updating binary variable by ++ in printf function.
Just simple don't free(binary); it will produce run time error because you are modifying binary variable inside printf *binary++: first save return address in a extra pointer variable then free that. Like I am doing:
b = binary=bin(a);
// loop
printf("%d", *binary++);
// ^ changing binary variable to point new memory location
// after loop
free(b);
If you free(binary) then it would be wrong because you would free a memory location that is not allocated dynamically because your are changing binary variable.
get a working code here, read comments.

Related

Element values show incorrect when print out from an array

I am just learning C and have my program print out incorrect values but I don't know how to fix it therefore I'd like to have your help.
Here is the codes . The test function stores integer numbers (from 0 to 20) in an array and return it. That array is copied to a new array (p[20]) in the main function and I try to print every element of that array out using for loop however the value is not correct, for example i = 0 then p[0] should be 0 but it shows -443987883 ,....
#include <stdio.h>
int test();
int main ()
{
int p[20];
strcpy(p , test);
int i;
int N = 20;
for (i=0; i < N; i++) {
printf ("%i,%i\n", i , p[i]);
}
}
int test (int i , char o[])
{
int N = 20;
for (i = 0; i < N; i++) {
o[i] = i;
}
return o;
}
Your code contains a lot of errors. I am going to point them out and explain to you how to fix it.
First of all, you should definitely forget the statement :
strcpy(p , test);
as by this you try to copy a function to an array! If you think that this statement calls test function and passes p as an argument to this, this is not true.
If you want another function, other than main, to fill your array, the best way would be to dynamically allocate a pointer to int and pass it by reference to the function. You can read more about passing by reference or by value here.
Let's see how you can do this. First of all, define N as a constant value outside your program :
#define N 20
Then, your main function should be modified like this :
int main ()
{
int *p;
int i;
//Dynamically allocate a pointer to ints
p = malloc(N*sizeof(int));
if (p == NULL)
printf ("Error in allocating memory\n");
//Now call your function
p = test(&p); //pass the pointer by reference
for (i = 0; i < N; i++)
printf ("%d, %d\n", i , p[i]);
}
and finally your test function should be modified accordingly like this :
int* test (int** p)
{
for (i = 0; i < N; i++)
*p[i] = i;
return *p;
}
So the prototype of your test function should change from :
int test();
to :
int* test(int**);

Initialising an int array in an if statement and using externally

New to C here and would appreciate if I could get some pointers.
I'm trying to initialise an array inside an if statement, and then print the values of the array externally - but I know the scope will be lost after the if block ends. I've tried creating the array with pointers. The reason I'm doing it inside the if statement is because the size of the array depends on a value calculated during runtime.
E.g.:
void createArray() {
int userInput;
printf("%s\n", "Please enter a value:");
scanf("%d\n", userInput);
if (userInput > 10) {
int array[userInput];
}
int i;
for (i = 0; i < userInput; i++) {
array[i] = i;
}
}
int i;
for (i = 0; i < sizeof(array)/sizeof(array[0]); i++) {
printf("%d\n", array[i]);
}
However because the array is declared inside a method, I obviously lose scope of it when it comes to the final for loop to print - thus an error occurs. I've tried creating a pointer variable int *array as a global variable, and inside the if statement, just staying array = int[10] but obviously this won't work.
This isn't my exact code, I've recreated a minimal example that shows my error so some syntax may be wrong here - apologies for that.
Any help would be appreciated.
One question you have to consider in your code is what happens if userInput is less than or equal to 10? You iterate over userInput elements of an array that was not declared.
One simple way of handling this is to make a large array at the beginning of your function and then use just the first userInput elements of it. This approach has obviously its limitations (e.g. userInput can't be larger than the size of the array, and you should make sure it won't be, otherwise bad things may happen), but is simple.
Another approach involves using dynamic memory allocation. This is done by using the malloc function:
int *array = malloc(100 * sizeof(int));
The code above allocates memory for 100 ints, basically creating an array of 100 elements. Then, you can use the array as usual. But, make sure you free it after you're done:
free(array);
Note that using this approach you'd need to declare the pointer first:
int *array;
if (userInput > 10) {
array = malloc(userInput * sizeof(int));
}
Below you can find a small proof of concept program. Note that instead of a global variable, the pointer value can be returned from the alloc function.
#include <stdio.h>
#include <stdlib.h>
int *arr;
void alloc() {
arr = malloc(10 * sizeof(int));
}
void assign() {
for (int i = 0; i < 10; i++)
arr[i] = i + i;
}
void print() {
for (int i = 0; i < 10; i++)
printf("%d\n", arr[i]);
}
int main(int argc, char *argv[])
{
alloc();
assign();
print();
free(arr);
return 0;
}
This allocates an array of int to the pointer intary. The pointer may be passed to other functions from main(). In main, userInput stores the number of int allocated.
#include <stdio.h>
#include <stdlib.h>
int *createArray( int *userInput);
int main( int argc, char *argv[])
{
int i;
int userInput = 0;
int *intary = NULL;
if ( ( intary = createArray ( &userInput)) != NULL ) {
for (i = 0; i < userInput; i++) {
intary[i] = i;
printf ( "%d\n", intary[i]);
}
free ( intary);
}
return 0;
}
int *createArray( int *userInput) {
int *array = NULL;
printf("%s\n", "Please enter a value:");
scanf("%d", userInput);
if ( *userInput > 10) {
if ( ( array = malloc ( *userInput * sizeof ( int))) == NULL) {
printf ( "could not allocate memory\n");
*userInput = 0;
return NULL;
}
}
else {
*userInput = 0;
return NULL;
}
return array;
}
You don't need some pointers, just one, (int* arr) and malloc(),a dynamic memory allocation function.
Note: You shouldn't use "array" as a variable name as it may create problems. So we'll name our variable arr.
If you're unfamiliar with it, i will explain the code too.
First add #include <stdlib.h> header file, which contains malloc().
Then declare a pointer of type int int* arr, we have named it arr in the createArray() scope.
We'll allocate the space required in the if condition with malloc() function, like :
void createArray() {
int userInput;
int* arr; // declare arr pointer
printf("%s\n", "Please enter a value:");
scanf("%d\n", userInput);
if (userInput > 10) {
arr = (int*) malloc ( userInput * sizeof(int) ); // explained below
}
int i;
for (i = 0; i < userInput; i++) {
arr[i] = i;
}
}
free(arr) // don't forget to free after using
[NOTE] This code is untested.
arr = (int*) malloc ( userInput * sizeof(int) );
This line may seem cryptic at first, but what it does is pretty simple , it allocates some memory dynamically on the heap.
The size of this memory is given by 'userInput * sizeof(int)', sizeof() function specifies the size of int on the given machine multiplied by userInput by the user,
Then, it is typecasted to int* type so that we can store the address in our int* type pointer arr.
[UPDATE] you can use arr = malloc ( userInput * sizeof(int) ); instead as suggested in comments, here is why Do I cast the result of malloc?

C pointer arithmetic palindrome

I'm a java student who's currently learning about pointers and C.
I tried to make a simple palindrome tester in C using a single array and pointer arithmetic.
I got it to work without a loop (example for an array of size 10 :*(test) == *(test+9) was true.
Having trouble with my loop. School me!
#include<stdio.h>
//function declaration
//int palindrome(int *test);
int main()
{
int output;
int numArray[10] = {0,2,3,4,1,1,4,3,2,0};
int *ptr;
ptr = &numArray[0];
output = palindrome(ptr);
printf("%d", output);
}
//function determine if string is a palindrome
int palindrome(int *test) {
int i;
for (i = 0; i <= (sizeof(test) / 2); i++) {
if (*(test + i) == *(test + (sizeof(test) - i)))
return 1;
else
return 0;
}
}
The Name of the array will itself acts as a pointer to an first element of the array, if you loose the pointer then there is no means for you to access the element of the array and hence you can send just the name of the array as a parameter to the function.
In the palindrome function:
you have used sizeof(test)/2. what happens is the address gets divided which is meaningless and hence you should not use that to calculate the mid element.
sizeof the pointer will be the same irrespective of the type of address that gets stored.
Why do you copy your pointer in another variable?
int *ptr;
ptr = &numArray[0];
Just send it to you function:
palindrome(numArray);
And sizeof(test) give you the memory size of a pointer, it's not what you want. You have to give the size in parameter of your function.
int palindrome(int *test, int size){
...
}
Finally your code must look like this:
#include<stdio.h>
int palindrome(int *test, int size);
int main()
{
int output;
int numArray[10] = {0,2,3,4,1,1,4,3,2,0};
output = palindrome(numArray, 10);
printf("%d", output);
}
//function determine if string is a palindrome
int palindrome(int *test, int size) {
int i;
for (i = 0; i < size / 2; i++) {
if (*(test + i) != *(test + (size - 1) - i))
return 0;
}
return 1;
}

How to get the information from a pointer [duplicate]

This question already has answers here:
Returning Arrays/Pointers from a function
(7 answers)
Closed 9 years ago.
Here is my code:
int *myFunction()
{
int A[3] = {1,2,3};
return A; //this will return the pointer to the first element in the array A
}
int main (void)
{
int A[3];
A = myfunction(); //A gets the return value of myFunction
for(int j=0; j==2; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
printf("%d",B);
return 0;
}
But this does not work because the A that is returned is not the actual vector. How do I get the actual vector {1,2,3} in the main function?
The function myFunction allocates A, but this allocation only exists within the scope of the function. When the function returns the memory holding A is destroyed. This means that the function is returning a pointer to memory that has not been un-allocated.
The problem is that the variable A does not persist outside the function. You could use a global variable or pass a pointer to the buffer into myFunction
Global variable method:
static int A[3];
int* myFunction()
{
A[0] = 1; A[1] = 2; //etc
return A;
}
In this example, because A is a global, the memory pointed to by A persists throught your program's entire life time. Therefore it is safe to return a pointer to it...
As a side note, global variables should probably not be used in this way... it's a little clunky. The use of the static keyword means that A will not be accessible outside of this module (C file).
Pointer method:
void myFunction(a[3])
{
a[0] = 1; a[1] = 2; //etc
}
int main()
{
myA[3];
myFunction(myA);
// and continue to print array...
}
In this example the main() function allocates myA. This variable exists whilst the function is executing (it's an automatic variable). A pointer to the array is passed into the function, which fills the array. Therefore the main() function can get information from myFunction().
Another way to make the variable myA persist would be to allocate it on the heap. To do this you would do something like int *myA = malloc(sizeof(int) * NUMBER_OF_INTS_IN_ARRAY. This memory will then persist until you specifically desctroy it using free() or you program ends.
int A[3] = {1,2,3}; is being created on the stack, this is, it is a local array and it's memory can be used again after myFunction executes. You have to either make int A[3] static within myFunction or by placing it outside of all functions. Another option would be to create int A[3] within main and pass the address of A to myFunction so myFunction can directly modify the contents of A.
As is, your code isn't close to working anyway... your for loop is broken, you have undefined variables in main, you have function name mismatches, and your print isn't going to do what you want anyway...
The big problem as that you've got undefined behavior going on, you can't access A[] outside of the function where it was locally defined. The easiest way to rectify that is to use dynamic memory, malloc() some memory for A in your myFunction then use the values in main and free() the memory when you're done.
Here's the example fixing your other syntax issues:
int *myFunction()
{
int *A;
A = malloc(3 * sizeof(int));
A[0] = 1;
A[1] = 2;
A[2] = 3;
return A;
}
int main (void)
{
int *A = myFunction(); //A gets the return value of myFunction
int B[3] = {0, 0, 0};
int j;
for(j=0; j<3; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
free(A);
printf("%d",B[0]);
return 0;
}
Pass the array to be filled as argument to the initisliser function along with its size:
size_t myFunction(int * A, size_t s)
{
int A_tmp[3] = {1,2,3};
size_t i = 0;
for (; i < s && i < sizeof(A_tmp)/sizeof(A_tmp[0]); ++i)
{
A[i] = A_tmp[i];
}
return i;
}
Then call it like so:
int main()
{
int myA[3];
size_t s = sizeof(myA)/sizeof(myA[0]);
size_t n = myFunction(myA, s);
if (n < s)
fprintf(stderr, "Caution: Only the first %zu of %zu elements of A were initialised.\n", n, s);
// and continue to print array...
}
#include <stdio.h>
int (*myFunction(void))[3]
{
static int A[3] = {1,2,3};
return &A;
}
int main (void){
int (*A)[3], B[3];
A = myFunction();
for(int j=0; j<=2; j++)
{
B[j] = 2 * (*A)[j];
}
for(int j=0; j<3;++j)
printf("%d ", B[j]);
return 0;
}

Segmentation fault when using malloc for 2D array

I create a 2-D array using malloc. When I use printf to print the array element in for loop, everything is fine. But when I want to use printf in main, these is a Segmentation fault: 11.
Could you please tell me what the problem with the following code is?
#include <stdlib.h>
#include <stdio.h>
void initCache(int **cache, int s, int E){
int i, j;
/* allocate memory to cache */
cache = (int **)malloc(s * sizeof(int *)); //set
for (i = 0; i < s; i++){
cache[i] = (int *)malloc(E * sizeof(int)); //int
for(j = 0; j < E; j++){
cache[i][j] = i + j;
printf("%d\n", cache[i][j]);
}
}
}
main()
{
int **c;
initCache (c, 2, 2);
printf("%d\n", c[1][1]); // <<<<<<<<<< here
}
Since your cache is a 2D array, it's int**. To set it in a function, pass int***, not int**. Otherwise, changes to cache made inside initCache have no effect on the value of c from main().
void initCache(int ***cache, int s, int E) {
int i, j;
/* allocate memory to cache */
*cache = (int **)malloc(s * sizeof(int *)); //set
for (i = 0; i < s; i++) {
(*cache)[i] = (int *)malloc(E * sizeof(int)); //int
for(j = 0; j < E; j++){
(*cache)[i][j] = i + j;
printf("%d\n", (*cache)[i][j]);
}
}
}
Now you can call it like this:
initCache (&c, 2, 2);
You changed a local variable, which won't effect the local variable c in main.
If you want to allocate in the function, why pass a variable? Return it from the function.
int **c = initCache(2, 2);
You could use a return, or else a *** as suggested by others. I'll describe the return method here.
initCache is creating and initializing a suitable array, but it is not returning it. cache is a local variable pointing to the data. There are two ways to make this information available to the calling function. Either return it, or pass in an int*** and use that to record the pointer value.
I suggest this:
int** initCache(int **cache, int s, int E){
....
return cache;
}
main()
{
int **c;
c = initCache (2, 2);
printf("%d\n", c[1][1]); <<<<<<<<<< here
}
====
Finally, it's very important to get in the habit of checking for errors. For example, malloc will return NULL if it has run out of memory. Also, you might accidentally as for a negative amount of memory (if s is negative). Therefore I would do:
cache = (int **)malloc(s * sizeof(int *));
assert(cache);
This will end the program if the malloc fails, and tell you what line has failed. Some people (including me!) would disapprove slightly of using assert like this. But we'd all agree it's better than having no error checking whatsoever!
You might need to #include <assert.h> to make this work.

Resources