Showing posts with label pointers. Show all posts
Showing posts with label pointers. Show all posts

14 August 2011

Never return a local pointer from a function

SA,

I am now try to write some example (will post here) on JNA (Java Native Access), so I am trying to write some simple cpp program...

While I am writing it, I've faced a problem ... And here's the story..

We always hear this phrase : "Never return a local pointer from a function"

Yes I know it good, but I usually forget it..

Here's some example that I took about 30 minutes investigate to know what's wrong!, and finally I realized this rule!:

#include <iostream>
#include <cstring>

using namespace std;

char* sayHelloFor(char*);

int main(void)
{
    
    char* ret = sayHelloFor("Ali");
    
    cout << ret << endl;;
    
    return 0;
}

char* sayHelloFor(char* name)
{
    char* hello = "Hello ";
    char str[40] = {'\0'};      // this is the local arrary/pointer
    strcat(str, hello);
    strcat(str, name);
    
    return str;
}

It returns some corrupted string (GCC on Windows)

And here's the correct code:

#include <iostream>
#include <cstring>

using namespace std;

void sayHelloFor(char*, char**);

int main(void)
{
    char c[40] = {0};
    char* ret = c;
    sayHelloFor("Ali", &ret);
    
    cout << ret << endl;;
    
    return 0;
}

void sayHelloFor(char* name, char** out)
{
    char* hello = "Hello ";
    //char str[40] = {'\0'};      // this is the local arrary/pointer
    strcat(*out, hello);
    strcat(*out, name);
    //return str;
}


02 June 2011

Playing with CGI

Hello,

I just want to play again with CGI, so today we will make a simple Hello Form.



And Here's the code:

First, the HTML Page:

<form action="/cgi-bin/sayHello" method="post" >
    <input type="text" name="username" />
    <input type="submit" value="say Hello" />
</form>

And the CGI Script (simple C++ program):

#include <iostream>
#include <cstdlib>
#include <cstring>

using std::cout;
using std::cin;
using std::endl;

int main(void)
{
    char* value = new char;
    cout<< "Content-type: text/html" << endl << endl;
    cin >> value;
    
    char* newValue = new char;
    
    bool toCpy = false;
    int cnt = 0;
    while (*value != '\0')
    {
        if (toCpy)
        {
            *newValue = *value;
            newValue++;
            cnt++;
        }
        
        if (toCpy == false && *value == '=') 
        {
            toCpy = true;
        }
        
        value++;
    }
    newValue = newValue - cnt;
    
    
    cout<<"Hello " << newValue<<endl;
}

20 September 2010

arrayCopy

Hi folks,

While looking at the usage of the method System.arraycopy
in Java, I found it very useful function.
for example, in java.util.ArrayList it is doing may useful shifting operations.

So, I decide to try to write a similar function, but instead of using the pattern "func (src, dest)" of java, I used instead the pattern "func(dest, src)" of C.

The Header file:
#ifndef ARRAYUTIL_H
#define ARRAYUTIL_H

#include <stddef.h>

/**
* dest destination array
* dIndex index to which we will start copying
* src source array
* sIndex index from which we will start copying
* len number of elements that will be copied from source array
* destArrLen the length of the destination array (hence C doesn't know any length info about passed arrays)
* size the size of the type of the array (ex: if the array of type long, put in this parameter sizeof(long))
*/
void arraryCopy(void *dest, int dIndex, const void* src, int sIndex, int len, int destArrLen, size_t size);

#endif // ARRAYUTIL_H


The impl file:
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

#include <arrays/ArrayUtil.h>

void arraryCopy(void *dest, int dIndex, const void* src, int sIndex, int len, int destLen, size_t size)
{
uint8_t *udest = (uint8_t*) dest;
uint8_t *usrc = (uint8_t*) src;
dIndex *= size;
sIndex *= size;
len *= size;
destLen *= size;

if (src != dest)
{
memcpy(&udest[dIndex], &usrc[sIndex], len);
}else
{
if (dIndex > sIndex)
{
uint8_t *tmp = (uint8_t*) calloc(destLen, size);
memcpy(tmp, &udest[dIndex], (destLen-dIndex));
memcpy(&udest[dIndex], &usrc[sIndex], len);
memcpy(&udest[dIndex+len], tmp, (destLen-dIndex));
free(tmp);
}else if (sIndex > dIndex)
{
memcpy(&udest[dIndex], &usrc[sIndex], (destLen-sIndex)+1);
}else
return;
}
}


And, testing it:
#include <stdio.h>
#include <arrays/ArrayUtil.h>

int main(void)
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

arraryCopy(arr, 1, arr, 2, 1, 10, sizeof(int));

int i;
for (i=0; i<9; i++) // the len became 9 here because we do shift left by 1
printf("%i ", arr[i]);

return 0;
}


20 July 2010

Some notes on pointers in C

Note the following simple program and Its output on GCC 3.2.3:


#include
#include

int main(void)
{
int *p;
printf("%p %i\n",p, *p);

int *p2 = malloc(sizeof(*p2));
printf("%p %i\n",p2, *p2);

int *p3 = NULL;
printf("%p \n",p3);

p3 = malloc(sizeof(*p3));
printf("%p %i\n",p3, *p3);
return 0;
}


The output is:

0x8048414 1474660693
0x8d3d008 0
(nil)
0x8d3d018 0


So, when you declare a pointer, it points to some garbage data.
When you malloc memory, the pointer points to some memory-allocated location.
When you assign NULL to a pointer, it becomes NULL Pointer and its address is NULL, and you need to reallocate memory for before use.

So,

30 June 2010

my_strcpy

#include <stdio.h>

void my_strcpy(const char*, char*);

static char str1[80] = "Good";
static char str2[80];

int main(void)
{
puts(str2);
my_strcpy(str1, str2);
puts(str2);
return 0;
}

void my_strcpy(const char* src, char* dest){
char* p;
p = dest;
while (*src!= '\0'){
*p++ = *src++;
}
*p = '\0';
}