17 martie 2011

Lucrul cu memoria



Cateva exemple pentru a reaminti cum se lucreaza cu pointerii ce refera zone de memorie:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

#include "utils.h"

char first_name[] = " Harry";
char last_name[] = " Potter";

static char *trim(char *s){

char *p = malloc(strlen(s)+1);
strcpy(p, s);
printf("p=%x\n",p);

int i=0;
while(*p == ' ') {
p++;
i++;
}

printf("p=%x\n",p);

s = malloc(sizeof(p)+1);
s = strcpy(s, p);
free(p-i);
return s;
}

int main(void){

printf("%s %s is learning SO!\n",
trim(first_name), trim(last_name));
return 0;
}

Programul sterge spatiile libere dintr-un nume si le afiseaza, iar la sfarsit elibereaza memoria. Pointerul p se tot deplaseaza pentru a referi zona de memorie urmatoare, insa cand se face free acesta trebuie sa fie pozitionat exact pe inceputul sirului de caractere.


#include "stdlib.h"
#include "stdio.h"

#include "utils.h"

int main(void)
{
int i;
unsigned int n = 0xDEADBEEF;
unsigned char *w;

/* TODO - use w to show all bytes of n in order */
i = -1;
w = (unsigned char*)(&n);
int dim = sizeof(n);
do {
i++;
printf("%x",*(w+dim-i)); // invers!

} while (i<=dim-1);

printf("\n");

return 0;
}

In acest program se scrie numarul n in hexa, folosind pointerul w care parcurge zona de memorie octet cu octet invers, din cauza little-endianess -ului (parcurgerea de la LSB la MSB). Daca sistemul ar fi fost big-endian , atunci parcurgerea s-ar fi facut *(w+i) si nu *(w+dim-i) .


In fine, un exemplu de folosire a variabilelor statice (cu rol de variabila globala, init cu 0):

#include "stdio.h"
#include "stdlib.h"

#include "utils.h"

/**
* TODO - functia inc() must behave like a counter
* The function returns the next value in order and
* does not receive and parameter
*
* You are not allowed to use global variables
*/
int inc()
{
static int c ;
c++;
return c;
}


int main(void)
{
int i;

for (i = 0;i<=10; i++)
printf("%d\n", inc());

return 0;
}

Niciun comentariu: