agrego practicas
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,143 @@
|
||||
#include "arena.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
char* arena_strdup(Arena* ref_arena, const char* s){
|
||||
char* str = (char*) arena_alloc(ref_arena, strlen(s) + 1);
|
||||
if(str == NULL){
|
||||
return NULL;
|
||||
}
|
||||
strcpy(str, s);
|
||||
return str;
|
||||
}
|
||||
|
||||
void* arena_chunk_alloc(Arena* ref_arena, Chunk* chunk, size_t s){
|
||||
size_t aligned = (chunk->offset + (ARENA_MEMORY_ALIGN - 1)) & ~(ARENA_MEMORY_ALIGN -1);
|
||||
if ((aligned + s <= chunk->size)){
|
||||
chunk->offset = aligned;
|
||||
void* start = (void *)(chunk->buffer + chunk->offset);
|
||||
chunk->offset = aligned + s;
|
||||
return start;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Chunk* arena_chunk_create(size_t s){
|
||||
printf("Creating a new chunk of %zu bytes\n", s);
|
||||
Chunk* chunk1 = (Chunk*)malloc(sizeof(Chunk));
|
||||
|
||||
if(chunk1 == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chunk1->size = s;
|
||||
chunk1->offset = 0;
|
||||
chunk1->next = NULL;
|
||||
|
||||
chunk1->buffer = (unsigned char *)malloc(s);
|
||||
|
||||
if(chunk1->buffer == NULL){
|
||||
perror("Error creando chunk...\n");
|
||||
free(chunk1);
|
||||
chunk1 = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("Chunk creado correctamente\n");
|
||||
|
||||
return chunk1;
|
||||
|
||||
}
|
||||
|
||||
void arena_chunk_free(Chunk* chunk){
|
||||
printf("Liberando %zu bytes de memoria\n", chunk->size);
|
||||
if(chunk->buffer != NULL){
|
||||
free(chunk->buffer);
|
||||
chunk->buffer = NULL;
|
||||
}
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
void* arena_alloc(Arena* ref_arena, size_t s){
|
||||
if(ref_arena == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ref_arena->current == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Chunk* current_chunk = ref_arena->current;
|
||||
|
||||
void* ptr = arena_chunk_alloc(ref_arena, current_chunk, s);
|
||||
|
||||
if(ptr == NULL){
|
||||
|
||||
size_t new_size = current_chunk->size * 2;
|
||||
|
||||
if(new_size < s){
|
||||
new_size = s;
|
||||
}
|
||||
|
||||
Chunk *new_chunk = arena_chunk_create(new_size);
|
||||
if(new_chunk == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
current_chunk->next = new_chunk;
|
||||
new_chunk->next = NULL;
|
||||
ref_arena->current = new_chunk;
|
||||
|
||||
return arena_alloc(ref_arena, s);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
|
||||
|
||||
}
|
||||
|
||||
Arena arena_create(size_t s){
|
||||
Arena new_arena = {
|
||||
.current = NULL,
|
||||
.first = NULL
|
||||
};
|
||||
|
||||
Chunk* chunk1 = arena_chunk_create(s);
|
||||
|
||||
if(chunk1 == NULL){
|
||||
perror("Error creando arena\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
new_arena.current = chunk1;
|
||||
new_arena.first = chunk1;
|
||||
|
||||
printf("Arena creada correctamente\n");
|
||||
|
||||
return new_arena;
|
||||
|
||||
}
|
||||
|
||||
void arena_free(Arena* ref_arena){
|
||||
Chunk* item = ref_arena->first;
|
||||
while (item != NULL) {
|
||||
Chunk *next = item->next;
|
||||
arena_chunk_free(item);
|
||||
item = next;
|
||||
}
|
||||
|
||||
ref_arena->first = NULL;
|
||||
ref_arena->current = NULL;
|
||||
|
||||
printf("Arena liberada\n");
|
||||
}
|
||||
|
||||
void arena_print(Arena* ref_arena){
|
||||
printf("ARENA INFO\n");
|
||||
printf("==========\n");
|
||||
|
||||
printf("first: %p\n", ref_arena->first);
|
||||
printf("next: %p\n", ref_arena->current);
|
||||
|
||||
printf("==========\n");
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define ARENA_MEMORY_ALIGN 8
|
||||
|
||||
typedef struct Chunk{
|
||||
size_t size;
|
||||
size_t offset;
|
||||
unsigned char *buffer;
|
||||
struct Chunk *next;
|
||||
}Chunk;
|
||||
|
||||
typedef struct{
|
||||
Chunk *current;
|
||||
Chunk *first;
|
||||
}Arena;
|
||||
|
||||
Arena arena_create(size_t);
|
||||
void* arena_alloc(Arena*, size_t);
|
||||
void arena_free(Arena*);
|
||||
void arena_print(Arena*);
|
||||
|
||||
Chunk* arena_chunk_create(size_t);
|
||||
void arena_chunk_free(Chunk*);
|
||||
void* arena_chunk_alloc(Arena*, Chunk*, size_t);
|
||||
|
||||
char* arena_strdup(Arena*, const char*);
|
||||
@@ -0,0 +1,90 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct{
|
||||
unsigned char *buffer;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
}Arena;
|
||||
|
||||
Arena arena_create(size_t);
|
||||
void* arena_alloc(Arena *, size_t);
|
||||
void arena_destroy(Arena *);
|
||||
|
||||
int main(void){
|
||||
Arena arena = arena_create(13);
|
||||
int *ptrInt1 = (int*)arena_alloc(&arena, sizeof(int));
|
||||
int *ptrInt2 = (int*)arena_alloc(&arena, sizeof(int));
|
||||
float *ptrFloat1 = (float*)arena_alloc(&arena, sizeof(float));
|
||||
char *ptrChar1 = (char*)arena_alloc(&arena, sizeof(char));
|
||||
|
||||
int need = sizeof(int)*2 + sizeof(float) + sizeof(char);
|
||||
|
||||
printf("sizeof int: %d\n", (int)sizeof(int));
|
||||
printf("sizeof float: %d\n", (int)sizeof(float));
|
||||
printf("sizeof char: %d\n", (int)sizeof(char));
|
||||
|
||||
printf("Necesitamos: %d\n", need);
|
||||
|
||||
if(ptrInt1 != NULL){
|
||||
*ptrInt1 = 18;
|
||||
printf("Primer entero: %d\n", *ptrInt1);
|
||||
}
|
||||
if(ptrInt2 != NULL){
|
||||
*ptrInt2 = 27;
|
||||
printf("Segundo entero: %d\n", *ptrInt2);
|
||||
}
|
||||
if(ptrFloat1 != NULL){
|
||||
*ptrFloat1 = 3.1415f;
|
||||
printf("Primer flotante: %f\n", *ptrFloat1);
|
||||
}
|
||||
if(ptrChar1 != NULL){
|
||||
*ptrChar1 = 'L';
|
||||
printf("Primer char: %c\n", *ptrChar1);
|
||||
}
|
||||
|
||||
arena_destroy(&arena);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Arena arena_create( size_t bytes){
|
||||
Arena new_arena = {
|
||||
.buffer = NULL,
|
||||
.size = bytes,
|
||||
.offset = 0
|
||||
};
|
||||
|
||||
new_arena.buffer = (unsigned char *)malloc(bytes);
|
||||
|
||||
if(new_arena.buffer == NULL){
|
||||
perror("Error asignando memoria");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return new_arena;
|
||||
|
||||
}
|
||||
void* arena_alloc(Arena *ref_arena, size_t bytes){
|
||||
|
||||
if(ref_arena->buffer == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ref_arena->offset + bytes > ref_arena->size){
|
||||
perror("Memoria llena\n");
|
||||
return NULL;
|
||||
}
|
||||
void* ptr_ref = ref_arena->buffer + ref_arena->offset;
|
||||
ref_arena->offset += bytes;
|
||||
return ptr_ref;
|
||||
}
|
||||
|
||||
void arena_destroy(Arena *ref_arena){
|
||||
if(ref_arena->buffer != NULL){
|
||||
free(ref_arena->buffer);
|
||||
ref_arena->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,82 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#define FPS 10
|
||||
|
||||
typedef struct{
|
||||
unsigned char *buffer;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
}Arena;
|
||||
|
||||
Arena arena_create(size_t);
|
||||
void* arena_alloc(Arena *, size_t);
|
||||
void arena_reset(Arena *);
|
||||
void arena_destroy(Arena *);
|
||||
|
||||
int main(void){
|
||||
srand(time(NULL));
|
||||
Arena arena = arena_create(100);
|
||||
|
||||
for(int i=0; i < FPS; i++){
|
||||
|
||||
int* ptrLeft = arena_alloc(&arena, sizeof(int));
|
||||
|
||||
if(ptrLeft != NULL){
|
||||
*ptrLeft = rand()%FPS;
|
||||
printf("El datos del frame es: %d\n", *ptrLeft);
|
||||
}
|
||||
|
||||
arena_reset(&arena);
|
||||
}
|
||||
|
||||
arena_destroy(&arena);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Arena arena_create( size_t bytes){
|
||||
Arena new_arena = {
|
||||
.buffer = NULL,
|
||||
.size = bytes,
|
||||
.offset = 0
|
||||
};
|
||||
|
||||
new_arena.buffer = (unsigned char *)malloc(bytes);
|
||||
|
||||
if(new_arena.buffer == NULL){
|
||||
perror("Error asignando memoria");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return new_arena;
|
||||
|
||||
}
|
||||
void* arena_alloc(Arena *ref_arena, size_t bytes){
|
||||
|
||||
if(ref_arena->buffer == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ref_arena->offset + bytes > ref_arena->size){
|
||||
perror("Memoria llena\n");
|
||||
return NULL;
|
||||
}
|
||||
void* ptr_ref = ref_arena->buffer + ref_arena->offset;
|
||||
ref_arena->offset += bytes;
|
||||
return ptr_ref;
|
||||
}
|
||||
|
||||
void arena_reset(Arena *ref_arena){
|
||||
ref_arena->offset = 0;
|
||||
}
|
||||
|
||||
void arena_destroy(Arena *ref_arena){
|
||||
if(ref_arena->buffer != NULL){
|
||||
free(ref_arena->buffer);
|
||||
ref_arena->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
+106
@@ -0,0 +1,106 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define FPS 10
|
||||
|
||||
#define ARENA_ALIGN 8
|
||||
|
||||
#define ALLOC_TYPE(REF, TYPE) (TYPE*)arena_alloc(&REF, sizeof(TYPE))
|
||||
|
||||
typedef struct{
|
||||
unsigned char *buffer;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
}Arena;
|
||||
|
||||
Arena arena_create(size_t);
|
||||
void* arena_alloc(Arena *, size_t);
|
||||
void arena_reset(Arena *);
|
||||
void arena_destroy(Arena *);
|
||||
bool arena_is_aligned(size_t);
|
||||
|
||||
int main(void){
|
||||
Arena arena = arena_create(32);
|
||||
|
||||
int *test = ALLOC_TYPE(arena, int);
|
||||
|
||||
*test = 5;
|
||||
|
||||
arena_alloc(&arena, 3);
|
||||
|
||||
arena_alloc(&arena, 1);
|
||||
arena_alloc(&arena, 5);
|
||||
arena_alloc(&arena, 9);
|
||||
arena_alloc(&arena, 8);
|
||||
arena_alloc(&arena, 1);
|
||||
|
||||
arena_destroy(&arena);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool arena_is_aligned(size_t pos){
|
||||
size_t mask = 7;
|
||||
return (pos & mask) == 0;
|
||||
}
|
||||
|
||||
Arena arena_create( size_t bytes){
|
||||
Arena new_arena = {
|
||||
.buffer = NULL,
|
||||
.size = bytes,
|
||||
.offset = 0
|
||||
};
|
||||
|
||||
new_arena.buffer = (unsigned char *)malloc(bytes);
|
||||
|
||||
if(new_arena.buffer == NULL){
|
||||
perror("Error asignando memoria");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return new_arena;
|
||||
|
||||
}
|
||||
void* arena_alloc(Arena *ref_arena, size_t bytes){
|
||||
|
||||
if(ref_arena->buffer == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t aligned = ((ref_arena->offset + (size_t)((ARENA_ALIGN - 1))) & ~(ARENA_ALIGN - 1));
|
||||
|
||||
if(aligned + bytes > ref_arena->size){
|
||||
printf("arena_alloc(%d): NULL \n", (int) bytes);
|
||||
return NULL;
|
||||
}
|
||||
void* ptr_ref = ref_arena->buffer + aligned;
|
||||
|
||||
printf("arena_alloc(%d) ", (int) bytes);
|
||||
|
||||
if(arena_is_aligned((size_t)ptr_ref)){
|
||||
printf("aligned: true ");
|
||||
}else{
|
||||
printf("aligned: false ");
|
||||
}
|
||||
|
||||
printf(" base + %d", (int)aligned);
|
||||
printf(" offset: %d -> %d \n", (int)ref_arena->offset, (int)aligned);
|
||||
|
||||
ref_arena->offset = aligned + bytes;
|
||||
|
||||
return ptr_ref;
|
||||
}
|
||||
|
||||
void arena_reset(Arena *ref_arena){
|
||||
ref_arena->offset = 0;
|
||||
}
|
||||
|
||||
void arena_destroy(Arena *ref_arena){
|
||||
if(ref_arena->buffer != NULL){
|
||||
free(ref_arena->buffer);
|
||||
ref_arena->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
+107
@@ -0,0 +1,107 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARENA_ALIGN 8
|
||||
|
||||
typedef struct{
|
||||
unsigned char *buffer;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
}Arena;
|
||||
|
||||
Arena arena_create(size_t);
|
||||
void* arena_alloc(Arena *, size_t);
|
||||
void arena_reset(Arena *);
|
||||
void arena_destroy(Arena *);
|
||||
bool arena_is_aligned(size_t);
|
||||
char* arena_strdup(Arena*, const char *);
|
||||
|
||||
int main(void){
|
||||
Arena arena = arena_create(16);
|
||||
|
||||
char* s1 = arena_strdup(&arena, "arena");
|
||||
char* s2 = arena_strdup(&arena, "hola");
|
||||
char* s3 = arena_strdup(&arena, "x");
|
||||
|
||||
arena_destroy(&arena);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char* arena_strdup(Arena* ref_arena, const char *src){
|
||||
char* ref_str = (char*) arena_alloc(ref_arena, strlen(src) + 1);
|
||||
if(ref_str == NULL){
|
||||
perror("No se ha podido reservar memoria para la cadena.");
|
||||
return NULL;
|
||||
}
|
||||
strcpy(ref_str, src);
|
||||
return ref_str;
|
||||
}
|
||||
|
||||
bool arena_is_aligned(size_t pos){
|
||||
size_t mask = 7;
|
||||
return (pos & mask) == 0;
|
||||
}
|
||||
|
||||
Arena arena_create( size_t bytes){
|
||||
Arena new_arena = {
|
||||
.buffer = NULL,
|
||||
.size = bytes,
|
||||
.offset = 0
|
||||
};
|
||||
|
||||
new_arena.buffer = (unsigned char *)malloc(bytes);
|
||||
|
||||
if(new_arena.buffer == NULL){
|
||||
perror("Error asignando memoria");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return new_arena;
|
||||
|
||||
}
|
||||
void* arena_alloc(Arena *ref_arena, size_t bytes){
|
||||
|
||||
if(ref_arena->buffer == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t aligned = ((ref_arena->offset + (size_t)((ARENA_ALIGN - 1))) & ~(ARENA_ALIGN - 1));
|
||||
|
||||
if(aligned + bytes > ref_arena->size){
|
||||
printf("arena_alloc(%d): NULL \n", (int) bytes);
|
||||
return NULL;
|
||||
}
|
||||
void* ptr_ref = ref_arena->buffer + aligned;
|
||||
|
||||
printf("arena_alloc(%d) ", (int) bytes);
|
||||
|
||||
if(arena_is_aligned((size_t)ptr_ref)){
|
||||
printf("aligned: true ");
|
||||
}else{
|
||||
printf("aligned: false ");
|
||||
}
|
||||
|
||||
printf(" base + %d", (int)aligned);
|
||||
printf(" offset: %d -> %d \n", (int)ref_arena->offset, (int)aligned);
|
||||
|
||||
ref_arena->offset = aligned + bytes;
|
||||
|
||||
return ptr_ref;
|
||||
}
|
||||
|
||||
void arena_reset(Arena *ref_arena){
|
||||
ref_arena->offset = 0;
|
||||
}
|
||||
|
||||
void arena_destroy(Arena *ref_arena){
|
||||
if(ref_arena->buffer != NULL){
|
||||
free(ref_arena->buffer);
|
||||
ref_arena->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
+120
@@ -0,0 +1,120 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARENA_ALIGN 8
|
||||
|
||||
typedef struct{
|
||||
unsigned char *buffer;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
}Arena;
|
||||
|
||||
Arena arena_create(size_t);
|
||||
void* arena_alloc(Arena *, size_t);
|
||||
void arena_reset(Arena *);
|
||||
void arena_destroy(Arena *);
|
||||
bool arena_is_aligned(size_t);
|
||||
size_t arena_checkpoint(Arena*);
|
||||
void arena_restore(Arena*, size_t);
|
||||
|
||||
int main(void){
|
||||
Arena arena = arena_create(32);
|
||||
|
||||
size_t cp0 = arena_checkpoint(&arena);
|
||||
int* x = (int*)arena_alloc(&arena, 8);
|
||||
|
||||
*x = 21;
|
||||
|
||||
arena_alloc(&arena, 8);
|
||||
size_t cp1 = arena_checkpoint(&arena);
|
||||
int* tmp = (int*)arena_alloc(&arena, 8);
|
||||
|
||||
arena_restore(&arena, cp1);
|
||||
|
||||
printf("x:%d\n", *x);
|
||||
|
||||
arena_alloc(&arena, 16);
|
||||
|
||||
arena_restore(&arena, cp0);
|
||||
|
||||
arena_alloc(&arena, 32);
|
||||
|
||||
arena_destroy(&arena);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void arena_restore(Arena* ref_arena, size_t chk){
|
||||
ref_arena->offset = chk;
|
||||
}
|
||||
|
||||
size_t arena_checkpoint(Arena* ref_arena){
|
||||
return ref_arena->offset;
|
||||
}
|
||||
|
||||
bool arena_is_aligned(size_t pos){
|
||||
size_t mask = 7;
|
||||
return (pos & mask) == 0;
|
||||
}
|
||||
|
||||
Arena arena_create( size_t bytes){
|
||||
Arena new_arena = {
|
||||
.buffer = NULL,
|
||||
.size = bytes,
|
||||
.offset = 0
|
||||
};
|
||||
|
||||
new_arena.buffer = (unsigned char *)malloc(bytes);
|
||||
|
||||
if(new_arena.buffer == NULL){
|
||||
perror("Error asignando memoria");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return new_arena;
|
||||
|
||||
}
|
||||
void* arena_alloc(Arena *ref_arena, size_t bytes){
|
||||
|
||||
if(ref_arena->buffer == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t aligned = ((ref_arena->offset + (size_t)((ARENA_ALIGN - 1))) & ~(ARENA_ALIGN - 1));
|
||||
|
||||
if(aligned + bytes > ref_arena->size){
|
||||
printf("arena_alloc(%d): NULL \n", (int) bytes);
|
||||
return NULL;
|
||||
}
|
||||
void* ptr_ref = ref_arena->buffer + aligned;
|
||||
|
||||
printf("arena_alloc(%d) ", (int) bytes);
|
||||
|
||||
if(arena_is_aligned((size_t)ptr_ref)){
|
||||
printf("aligned: true ");
|
||||
}else{
|
||||
printf("aligned: false ");
|
||||
}
|
||||
|
||||
printf(" base + %d", (int)aligned);
|
||||
printf(" offset: %d -> %d \n", (int)ref_arena->offset, (int)aligned);
|
||||
|
||||
ref_arena->offset = aligned + bytes;
|
||||
|
||||
return ptr_ref;
|
||||
}
|
||||
|
||||
void arena_reset(Arena *ref_arena){
|
||||
ref_arena->offset = 0;
|
||||
}
|
||||
|
||||
void arena_destroy(Arena *ref_arena){
|
||||
if(ref_arena->buffer != NULL){
|
||||
free(ref_arena->buffer);
|
||||
ref_arena->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
+178
@@ -0,0 +1,178 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define ARENA_MEMORY_ALIGN 8
|
||||
|
||||
typedef struct Chunk{
|
||||
size_t size;
|
||||
size_t offset;
|
||||
unsigned char *buffer;
|
||||
struct Chunk *next;
|
||||
}Chunk;
|
||||
|
||||
typedef struct{
|
||||
Chunk *current;
|
||||
Chunk *first;
|
||||
}Arena;
|
||||
|
||||
Arena arena_create(size_t);
|
||||
void* arena_alloc(Arena*, size_t);
|
||||
void arena_free(Arena*);
|
||||
void arena_print(Arena*);
|
||||
|
||||
Chunk* arena_chunk_create(size_t);
|
||||
void arena_chunk_free(Chunk*);
|
||||
void* arena_chunk_alloc(Arena*, Chunk*, size_t);
|
||||
|
||||
int main(void){
|
||||
|
||||
Arena arena = arena_create(32);
|
||||
|
||||
arena_print(&arena);
|
||||
|
||||
arena_alloc(&arena, 100);
|
||||
|
||||
arena_print(&arena);
|
||||
|
||||
arena_alloc(&arena, 40);
|
||||
|
||||
arena_print(&arena);
|
||||
|
||||
arena_free(&arena);
|
||||
|
||||
arena_print(&arena);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* arena_chunk_alloc(Arena* ref_arena, Chunk* chunk, size_t s){
|
||||
size_t aligned = (chunk->offset + (ARENA_MEMORY_ALIGN - 1)) & ~(ARENA_MEMORY_ALIGN -1);
|
||||
if ((aligned + s <= chunk->size)){
|
||||
chunk->offset = aligned;
|
||||
void* start = (void *)(chunk->buffer + chunk->offset);
|
||||
chunk->offset = aligned + s;
|
||||
return start;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Chunk* arena_chunk_create(size_t s){
|
||||
printf("Creating a new chunk of %zu bytes\n", s);
|
||||
Chunk* chunk1 = (Chunk*)malloc(sizeof(Chunk));
|
||||
|
||||
if(chunk1 == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chunk1->size = s;
|
||||
chunk1->offset = 0;
|
||||
chunk1->next = NULL;
|
||||
|
||||
chunk1->buffer = (unsigned char *)malloc(s);
|
||||
|
||||
if(chunk1->buffer == NULL){
|
||||
perror("Error creando chunk...\n");
|
||||
free(chunk1);
|
||||
chunk1 = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("Chunk creado correctamente\n");
|
||||
|
||||
return chunk1;
|
||||
|
||||
}
|
||||
|
||||
void arena_chunk_free(Chunk* chunk){
|
||||
printf("Liberando %zu bytes de memoria\n", chunk->size);
|
||||
if(chunk->buffer != NULL){
|
||||
free(chunk->buffer);
|
||||
chunk->buffer = NULL;
|
||||
}
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
void* arena_alloc(Arena* ref_arena, size_t s){
|
||||
if(ref_arena == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ref_arena->current == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Chunk* current_chunk = ref_arena->current;
|
||||
|
||||
void* ptr = arena_chunk_alloc(ref_arena, current_chunk, s);
|
||||
|
||||
if(ptr == NULL){
|
||||
|
||||
size_t new_size = current_chunk->size * 2;
|
||||
|
||||
if(new_size < s){
|
||||
new_size = s;
|
||||
}
|
||||
|
||||
Chunk *new_chunk = arena_chunk_create(new_size);
|
||||
if(new_chunk == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
current_chunk->next = new_chunk;
|
||||
new_chunk->next = NULL;
|
||||
ref_arena->current = new_chunk;
|
||||
|
||||
return arena_alloc(ref_arena, s);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
|
||||
|
||||
}
|
||||
|
||||
Arena arena_create(size_t s){
|
||||
Arena new_arena = {
|
||||
.current = NULL,
|
||||
.first = NULL
|
||||
};
|
||||
|
||||
Chunk* chunk1 = arena_chunk_create(s);
|
||||
|
||||
if(chunk1 == NULL){
|
||||
perror("Error creando arena\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
new_arena.current = chunk1;
|
||||
new_arena.first = chunk1;
|
||||
|
||||
printf("Arena creada correctamente\n");
|
||||
|
||||
return new_arena;
|
||||
|
||||
}
|
||||
|
||||
void arena_free(Arena* ref_arena){
|
||||
Chunk* item = ref_arena->first;
|
||||
while (item != NULL) {
|
||||
Chunk *next = item->next;
|
||||
arena_chunk_free(item);
|
||||
item = next;
|
||||
}
|
||||
|
||||
ref_arena->first = NULL;
|
||||
ref_arena->current = NULL;
|
||||
|
||||
printf("Arena liberada\n");
|
||||
}
|
||||
|
||||
void arena_print(Arena* ref_arena){
|
||||
printf("ARENA INFO\n");
|
||||
printf("==========\n");
|
||||
|
||||
printf("first: %p\n", ref_arena->first);
|
||||
printf("next: %p\n", ref_arena->current);
|
||||
|
||||
printf("==========\n");
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include "../arena-lib/arena.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef struct Persona{
|
||||
char* nombre;
|
||||
int edad;
|
||||
struct Persona* next;
|
||||
}Persona;
|
||||
|
||||
void print_persona(Persona*);
|
||||
|
||||
|
||||
int main(void){
|
||||
|
||||
printf("Alinacion struct Persona: %d\n", (int)_Alignof(Persona));
|
||||
printf("sizeof struct Persona: %d\n", (int)sizeof(Persona));
|
||||
|
||||
Arena arena = arena_create(32);
|
||||
|
||||
char continuar = 'S';
|
||||
|
||||
Persona* first = NULL;
|
||||
Persona* last = NULL;
|
||||
|
||||
do{
|
||||
char input_name[50];
|
||||
printf("Nombre:");
|
||||
if (fgets(input_name, sizeof(input_name), stdin) != NULL) {
|
||||
input_name[strcspn(input_name, "\n")] = '\0';
|
||||
}
|
||||
|
||||
int input_edad = 0;
|
||||
|
||||
printf("Edad:");
|
||||
scanf("%d", &input_edad);
|
||||
printf("\n");
|
||||
|
||||
int c;
|
||||
while ((c = getchar()) != '\n' && c != EOF);
|
||||
|
||||
Persona* p = (Persona*)arena_alloc(&arena, sizeof(Persona));
|
||||
|
||||
if(p == NULL){
|
||||
perror("Ha ocurrido un error\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
p->nombre = arena_strdup(&arena, input_name);
|
||||
p->edad = input_edad;
|
||||
p->next = NULL;
|
||||
|
||||
if(first == NULL){
|
||||
first = p;
|
||||
}
|
||||
|
||||
if(last != NULL){
|
||||
last->next = p;
|
||||
}
|
||||
|
||||
last = p;
|
||||
|
||||
printf("Cargar mas personas? (S) Continuar, (N): Terminar :");
|
||||
scanf(" %c", &continuar);
|
||||
|
||||
while ((c = getchar()) != '\n' && c != EOF);
|
||||
|
||||
}while((continuar == 'S') || (continuar == 's'));
|
||||
|
||||
printf("Listado de personas cargadas:\n");
|
||||
printf("=============================\n");
|
||||
|
||||
Persona* current = first;
|
||||
while(current != NULL){
|
||||
print_persona(current);
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
arena_free(&arena);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_persona(Persona* ref_persona) {
|
||||
printf("%s: tiene %d years\n", ref_persona->nombre, ref_persona->edad);
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
+102
@@ -0,0 +1,102 @@
|
||||
#include "../arena-lib/arena.h"
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
BIN_OP_SUMA,
|
||||
BIN_OP_RESTA,
|
||||
BIN_OP_MULTIPLY,
|
||||
BIN_OP_DIVISION
|
||||
} BinaryOps;
|
||||
|
||||
typedef enum {
|
||||
NODE_NUMBER,
|
||||
NODE_OPERATION
|
||||
} NodeKind;
|
||||
|
||||
typedef struct Node{
|
||||
union {
|
||||
BinaryOps operation;
|
||||
int number;
|
||||
}value;
|
||||
NodeKind type;
|
||||
struct Node* left;
|
||||
struct Node* right;
|
||||
} Node;
|
||||
|
||||
Node* create_number(Arena* arena_ref, int n){
|
||||
Node* node = (Node*)arena_alloc(arena_ref, sizeof(Node));
|
||||
if(node == NULL){
|
||||
return NULL;
|
||||
}
|
||||
node->type = NODE_NUMBER;
|
||||
node->value.number = n;
|
||||
node->left = NULL;
|
||||
node->right = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
Node* create_operation(Arena* ref_arena, BinaryOps op, Node* l, Node* r){
|
||||
Node* node = (Node*)arena_alloc(ref_arena, sizeof(Node));
|
||||
if(node == NULL){
|
||||
return NULL;
|
||||
}
|
||||
node->type = NODE_OPERATION;
|
||||
node->value.operation = op;
|
||||
node->left = l;
|
||||
node->right = r;
|
||||
return node;
|
||||
}
|
||||
|
||||
int node_compute(Node* node){
|
||||
if(node->type == NODE_OPERATION){
|
||||
int r1 = node_compute(node->left);
|
||||
int r2 = node_compute(node->right);
|
||||
int result = 0;
|
||||
switch (node->value.operation) {
|
||||
case BIN_OP_SUMA:
|
||||
result = r1 + r2;
|
||||
break;
|
||||
case BIN_OP_RESTA:
|
||||
result = r1 - r2;
|
||||
break;
|
||||
case BIN_OP_MULTIPLY:
|
||||
result = r1 * r2;
|
||||
break;
|
||||
case BIN_OP_DIVISION:
|
||||
result = (r2 != 0) ? r1 / r2 : 0;
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return node->value.number;
|
||||
}
|
||||
|
||||
int main(void){
|
||||
|
||||
Arena arena = arena_create(32);
|
||||
|
||||
printf("Memory struct information\n");
|
||||
printf("=========================\n");
|
||||
printf("sizeof(Node):%zu\n", sizeof(Node));
|
||||
printf("align(Node): %zu\n", _Alignof(Node));
|
||||
|
||||
//Creamos el arbol para 3 + (4 - 1)
|
||||
Node* t1 = create_number(&arena, 3);
|
||||
Node* t21 = create_number(&arena, 4);
|
||||
Node* t22 = create_number(&arena, 1);
|
||||
Node* t2 = create_operation(&arena, BIN_OP_RESTA, t21, t22);
|
||||
Node* root = create_operation(&arena, BIN_OP_SUMA, t1, t2);
|
||||
|
||||
printf("Node compute\n");
|
||||
printf("============\n");
|
||||
|
||||
printf("result: %d\n", node_compute(root));
|
||||
|
||||
arena_free(&arena);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,73 @@
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include<stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include<unistd.h>
|
||||
#include<getopt.h>
|
||||
|
||||
|
||||
static struct option option_args[] = {
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{"verbose", no_argument, 0, 'v' },
|
||||
{"output", required_argument, 0, 'o' },
|
||||
{"max", required_argument, 0, 'm' },
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
void print_usage(char* arg){
|
||||
fprintf(stdout, "Uso: %s\n", arg);
|
||||
fprintf(stdout, "[--help]\n");
|
||||
fprintf(stdout, "[--verbose]\n");
|
||||
fprintf(stdout, "[--output <archivo>]\n");
|
||||
fprintf(stdout, "[--max <num>]\n");
|
||||
fprintf(stdout, "[posicionales...]\n");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
printf("argv[0]: %s\n", argv[0]);
|
||||
|
||||
int opt;
|
||||
int opt_index = 0;
|
||||
|
||||
while((opt = getopt_long(argc, argv, "hvo:m:", option_args, &opt_index)) != -1){
|
||||
switch (opt){
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
exit(0);
|
||||
break;
|
||||
case 'v':
|
||||
fprintf(stdout, "Modo verbose: ON\n");
|
||||
break;
|
||||
case 'o':
|
||||
fprintf(stdout, "Output: %s\n", optarg);
|
||||
break;
|
||||
case 'm':
|
||||
errno = 0;
|
||||
char* errorptr = NULL;
|
||||
long maximo = strtol(optarg, &errorptr, 10);
|
||||
if( (errno == EINVAL)
|
||||
|| (errno == ERANGE)
|
||||
|| (*errorptr != 0)
|
||||
|| (maximo < INT_MIN)
|
||||
|| (maximo > INT_MAX)
|
||||
){
|
||||
fprintf(stderr, "--max debe ser un numero entero valido.\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("Maximo:%ld\n", maximo);
|
||||
break;
|
||||
case '?':
|
||||
print_usage(argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "Posicionales:\n");
|
||||
for(int i = optind; i < argc; i++){
|
||||
fprintf(stdout, "%s\n", argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Enunciado del Ejercicio: Modificación de Arreglos mediante Aritmética de Punteros
|
||||
*
|
||||
* Objetivo:
|
||||
* Practicar el manejo de punteros y su relación con los arreglos estáticos en el lenguaje C,
|
||||
* aplicando aritmética de punteros para recorrer y modificar los elementos almacenados en memoria.
|
||||
*
|
||||
* Descripción:
|
||||
*
|
||||
* Escribe un programa completo en C que realice las siguientes tareas:
|
||||
*
|
||||
* Declaración e Inicialización:
|
||||
*
|
||||
* Declara un arreglo estático de 5 enteros (int) e inicialízalo
|
||||
* con valores arbitrarios de tu elección (por ejemplo: 5, 10, 15, 20, 25).
|
||||
*
|
||||
* Declara un puntero a entero (int *ptr) que apunte al inicio del arreglo.
|
||||
*
|
||||
* Procesamiento con Aritmética de Punteros:
|
||||
*
|
||||
* Utiliza un bucle (for o el de tu preferencia) para recorrer el arreglo únicamente mediante
|
||||
* aritmética de punteros y el operador de indirección en la forma *(ptr + i) (o incrementando el puntero directamente).
|
||||
*
|
||||
* Dentro del bucle, suma 10 al valor actual almacenado en cada posición del arreglo.
|
||||
*
|
||||
* Salida por Consola:
|
||||
*
|
||||
* Muestra en pantalla los valores del arreglo antes y después de aplicar la modificación
|
||||
* para verificar que el cambio se realizó correctamente en la memoria del arreglo original.
|
||||
*
|
||||
* Restricciones:
|
||||
*
|
||||
* Está prohibido utilizar la notación de corchetes (arreglo[i]) para acceder o modificar
|
||||
* los elementos del arreglo dentro del bucle. Debes usar estrictamente la sintaxis de punteros (*(ptr + i)).
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define V_LENGTH 5
|
||||
|
||||
void print_arr(int *);
|
||||
|
||||
int main(void){
|
||||
int v1[V_LENGTH] = {5, 10, 15, 20, 25};
|
||||
int* ptr_v1 = v1;
|
||||
print_arr(ptr_v1);
|
||||
for(int i=0; i<V_LENGTH; i++){
|
||||
*(ptr_v1 + i) += 10;
|
||||
}
|
||||
print_arr(ptr_v1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_arr(int *arr){
|
||||
printf("Array: ");
|
||||
for(int i = 0; i < V_LENGTH; i++){
|
||||
printf(" %d,", *(arr + i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* El objetivo es escribir un codigo donde falle al intentar modificar el contenido de un puntero
|
||||
* y tambien falle al intentar modificar a donde apunta otro puntero.
|
||||
*/
|
||||
|
||||
|
||||
int main(void){
|
||||
int sensor_temp = 25;
|
||||
int sensor_humedad = 60;
|
||||
int ipa = 192;
|
||||
int ipb = 168;
|
||||
const int *ptr_lectura = &sensor_temp;
|
||||
int * const ptr_config = &ipa;
|
||||
|
||||
ptr_lectura = &sensor_humedad;
|
||||
|
||||
//No debo poder modificar el valor del sensor mediante el puntero.
|
||||
*ptr_lectura = 44;
|
||||
|
||||
*ptr_config = 10;
|
||||
|
||||
//No debo poder cambiar a donde apunta el puntero ptr_config.
|
||||
ptr_config = &ipb;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
Se encontraron 3 registros invalidos.
|
||||
Iniciando reporte.
|
||||
Procesando 128 registros.
|
||||
Reporte generado correctamente.
|
||||
@@ -0,0 +1 @@
|
||||
Se encontraron 3 registros invalidos.
|
||||
@@ -0,0 +1,7 @@
|
||||
Permissions Size User Date Modified Name
|
||||
.rw-r--r-- 38 horacio 28 Oct 10:58 errores.txt
|
||||
.rw-r--r-- 0 horacio 28 Oct 11:07 listado.txt
|
||||
.rw-r--r-- 271 horacio 28 Oct 10:55 main.c
|
||||
.rwxr-xr-x 16k horacio 28 Oct 10:56 programa
|
||||
.rw-r--r-- 24 horacio 28 Oct 11:04 salida.txt
|
||||
.rw-r--r-- 19 horacio 28 Oct 11:00 test.txt
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <stdio.h>
|
||||
int main(void){
|
||||
fprintf(stdout, "Iniciando reporte.\n");
|
||||
fprintf(stdout, "Procesando 128 registros.\n");
|
||||
fprintf(stdout, "Reporte generado correctamente.\n");
|
||||
|
||||
fprintf(stderr, "Se encontraron 3 registros invalidos.\n");
|
||||
return 1;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
Iniciando reporte.
|
||||
Procesando 128 registros.
|
||||
Reporte generado correctamente.
|
||||
@@ -0,0 +1,2 @@
|
||||
test
|
||||
segunda linea
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
int main(void){
|
||||
int c, count = 0, countbr = 0;
|
||||
|
||||
while((c = getchar()) != EOF){
|
||||
if(c == '\n'){
|
||||
countbr++;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
fprintf(stdout, "Se leyeron %d bytes\n", count);
|
||||
fprintf(stdout, "Se leyeron %d <br> \n", countbr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cppbuild",
|
||||
"label": "C/C++: gcc build active file",
|
||||
"command": "/usr/bin/gcc",
|
||||
"args": [
|
||||
"-fdiagnostics-color=always",
|
||||
"-g",
|
||||
"${file}",
|
||||
"-o",
|
||||
"${fileDirname}/${fileBasenameNoExtension}"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${fileDirname}"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"detail": "Task generated by Debugger."
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
este es un archivo
|
||||
de texto
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,42 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int count_words(char*);
|
||||
|
||||
int main(void){
|
||||
|
||||
char buffer[50];
|
||||
int total_words = 0;
|
||||
|
||||
while((fgets(buffer, sizeof(buffer), stdin)) != NULL){
|
||||
total_words += count_words(buffer);
|
||||
}
|
||||
|
||||
printf("El total de palabras es: %d\n", total_words);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count_words(char* line){
|
||||
int palabras = 0;
|
||||
bool hay_espacio = false;
|
||||
|
||||
printf("line: %s", line);
|
||||
|
||||
if((line[0] != ' ') && strlen(line) > 0){
|
||||
palabras++;
|
||||
}
|
||||
|
||||
for(int i = 0; i < strlen(line); i++){
|
||||
if(line[i] == ' '){
|
||||
hay_espacio = true;
|
||||
}
|
||||
|
||||
if((line[i] != ' ') && (line[i] != '\n') && (hay_espacio)){
|
||||
palabras++;
|
||||
hay_espacio = false;
|
||||
}
|
||||
}
|
||||
return palabras;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* EJERCICIO DE LENGUAJE C: STRUCTS Y PUNTEROS
|
||||
*
|
||||
* 1. Define una struct llamada Coordenada que contenga dos campos enteros: x e y.
|
||||
* 2. Implementa una función constructora llamada Coordenada* crear_coordenada(int x, int y) que:
|
||||
* - Reserve memoria dinámicamente utilizando malloc para una nueva estructura Coordenada.
|
||||
* - Verifique si la reserva de memoria fue exitosa.
|
||||
* - Inicialice sus campos x e y con los valores pasados como parámetros.
|
||||
* - Devuelva el puntero a la estructura creada.
|
||||
* 3. En la función main:
|
||||
* - Utiliza la función constructora para crear una coordenada.
|
||||
* - Muestra por pantalla los valores iniciales utilizando el operador flecha (->).
|
||||
* - Modifica los valores de los campos de la estructura utilizando también el operador flecha (->).
|
||||
* - Muestra los nuevos valores por pantalla.
|
||||
* - Libera la memoria reservada dinámicamente utilizando free para evitar pérdidas de memoria.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
typedef struct{
|
||||
int x;
|
||||
int y;
|
||||
}Coordenada;
|
||||
|
||||
Coordenada* crear_coordenada(int x, int y);
|
||||
void modificar_coordenada(Coordenada**, int x, int y);
|
||||
void imprimir_coordenada(Coordenada**);
|
||||
|
||||
int main(void){
|
||||
|
||||
Coordenada* cord = crear_coordenada(10, 20);
|
||||
|
||||
imprimir_coordenada(&cord);
|
||||
modificar_coordenada(&cord, 30, 40);
|
||||
imprimir_coordenada(&cord);
|
||||
|
||||
free(cord);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Coordenada* crear_coordenada(int x, int y){
|
||||
Coordenada* new_cord = malloc(sizeof(Coordenada));
|
||||
if(new_cord == NULL){
|
||||
perror("No se pudo crear la coordenada\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
new_cord->x = x;
|
||||
new_cord->y = y;
|
||||
|
||||
return new_cord;
|
||||
}
|
||||
|
||||
void modificar_coordenada(Coordenada** cord_address, int x, int y){
|
||||
if((*cord_address) == NULL){
|
||||
perror("No se ha proporcionado una coordenada para modificar\n");
|
||||
exit(1);
|
||||
}
|
||||
(*cord_address)->x = x;
|
||||
(*cord_address)->y = y;
|
||||
}
|
||||
|
||||
void imprimir_coordenada(Coordenada** a){
|
||||
printf("Coordenada(%d, %d);\n", (*a)->x, (*a)->y);
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,92 @@
|
||||
/*******************************************************************************
|
||||
* TRABAJO PRÁCTICO / EJERCICIO INTEGRADOR: GESTIÓN DE PUNTEROS Y ESTRUCTURAS
|
||||
*
|
||||
* OBJETIVO:
|
||||
* El propósito de este ejercicio es consolidar el manejo de estructuras,
|
||||
* aritmética de punteros, indirección y diseño de funciones conpaso por referencia
|
||||
* en el lenguaje C, evitando el uso de código resuelto y enfocándose en la
|
||||
* especificación formal del problema.
|
||||
*
|
||||
* CONSIGNA:
|
||||
* Desarrolle un programa en Lenguaje C que cumpla rigurosamente con los
|
||||
* siguientes requerimientos técnicos y estructurales:
|
||||
*
|
||||
* 1. Definición del Tipo de Dato (Struct con Punteros Internos):
|
||||
* - Defina una estructura denominada `Persona` que contenga dos campos:
|
||||
* * Un puntero a caracteres (`char *nombre`) destinado a almacenar
|
||||
* dinámicamente o mediante literales la identificación de la persona.
|
||||
* * Un número entero (`int edad`) que represente los años de la persona.
|
||||
*
|
||||
* 2. Estructura de Almacenamiento (Arreglo de Estructuras):
|
||||
* - En la función principal (`main`), declare un arreglo estático con
|
||||
* capacidad exactamente para 3 elementos de tipo `Persona`.
|
||||
* - Inicialice cada uno de los elementos del arreglo asignando valores
|
||||
* válidos tanto para el puntero `nombre` como para la `edad`.
|
||||
* - Implemente una función específica (cuya firma y diseño quedan a su cargo)
|
||||
* que reciba como parámetro el puntero al inicio del arreglo de estructuras
|
||||
* y su tamaño, y se encargue de recorrerlo sistemáticamente para
|
||||
* imprimir en la consola los datos de todos sus elementos.
|
||||
*
|
||||
* 3. Encapsulamiento y Modificación (Funciones Modificadoras / Setters):
|
||||
* - Escriba una función modular de tipo `void` llamada `cambiar_edad`
|
||||
* cuya firma obligatoria sea:
|
||||
* `void cambiar_edad(Persona *p, int nueva_edad)`
|
||||
* - Dicha función debe recibir un puntero a una estructura `Persona`
|
||||
* para actualizar el campo correspondiente de forma segura mediante
|
||||
* el operador de indirección adecuado, reflejando el cambio en el ámbito
|
||||
* del programa principal.
|
||||
*
|
||||
* 4. Pautas de Entrega y Validación:
|
||||
* - El programa debe compilar sin errores ni advertencias bajo un estándar
|
||||
* moderno de C (por ejemplo, -std=c11 o superior).
|
||||
* - No se deben utilizar variables globales; toda la comunicación entre
|
||||
* funciones debe realizarse mediante parámetros y punteros.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define P_LENGTH 3
|
||||
|
||||
typedef struct{
|
||||
char* nombre;
|
||||
int edad;
|
||||
}Persona;
|
||||
|
||||
void listar_personas(Persona*, int length);
|
||||
void cambiar_edad(Persona *p, int nueva_edad);
|
||||
|
||||
int main(void){
|
||||
|
||||
Persona personas[P_LENGTH] = {
|
||||
{
|
||||
.nombre = "Horacio",
|
||||
.edad = 43
|
||||
},
|
||||
{
|
||||
.nombre = "Raquel",
|
||||
.edad = 44
|
||||
}, {
|
||||
.nombre = "Luna",
|
||||
.edad = 15
|
||||
}
|
||||
};
|
||||
|
||||
listar_personas(personas, P_LENGTH);
|
||||
cambiar_edad(personas, 21);
|
||||
cambiar_edad(personas+1, 22);
|
||||
cambiar_edad(personas+2, -5);
|
||||
listar_personas(personas, P_LENGTH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void listar_personas(Persona* p, int length){
|
||||
for(int i=0; i < length; i++){
|
||||
printf("%s \t %d \n", (p+i)->nombre, (p+i)->edad);
|
||||
}
|
||||
}
|
||||
|
||||
void cambiar_edad(Persona *p, int nueva_edad){
|
||||
p->edad = nueva_edad;
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,347 @@
|
||||
/* =========================================================================
|
||||
* PROYECTO: Sistema de Registro y Telemetría para el Nanosatélite "Andrómeda-1"
|
||||
* -------------------------------------------------------------------------
|
||||
* CONTEXTO:
|
||||
* La Agencia Espacial Experimental está desarrollando el software de a bordo
|
||||
* para su próximo nanosatélite. El sistema necesita gestionar memoria de
|
||||
* forma dinámica y eficiente debido a los recursos limitados del microcontrolador
|
||||
* y a la naturaleza impredecible de las ráfagas de datos en órbita.
|
||||
*
|
||||
* OBJETIVO:
|
||||
* Diseñar e implementar un programa en lenguaje C que resuelva los siguientes
|
||||
* módulos de gestión de memoria dinámica requeridos por la estación de tierra:
|
||||
*
|
||||
* 1. Vector Dinámico Básico (Canales de Sensores):
|
||||
* Pide al operador un número N de canales activos, utiliza malloc para
|
||||
* reservar un arreglo de enteros con las lecturas iniciales, muéstralo en
|
||||
* consola y libera correctamente la memoria con free al terminar.
|
||||
*
|
||||
* 2. Cadenas Dinámicas (Identificadores de Misión):
|
||||
* Escribe una función que reciba una cadena estática (char *) con el nombre
|
||||
* de código del satélite, calcule su longitud exacta, reserve espacio
|
||||
* dinámicamente con malloc, copie la cadena y devuelva el nuevo puntero
|
||||
* dinámico para ser registrado en los logs del sistema.
|
||||
*
|
||||
* 3. Estructura Dinámica (Buffer de Archivos de Telemetría):
|
||||
* Define una struct Archivo que contenga dos campos: size_t tamano y
|
||||
* uint8_t *datos. Escribe una función que reciba el tamaño deseado y reserve
|
||||
* memoria dinámicamente tanto para la estructura en sí como para su búfer
|
||||
* interno de datos binarios.
|
||||
*
|
||||
* 4. Redimensionamiento con realloc (Stream de Datos en Tiempo Real):
|
||||
* Crea una rutina que lea números enteros (paquetes de telemetría) desde
|
||||
* la consola de forma indefinida hasta una condición de parada. Almacénalos
|
||||
* en un arreglo dinámico que duplique su tamaño cada vez que se llene
|
||||
* utilizando realloc para optimizar el almacenamiento.
|
||||
*
|
||||
* 5. Estructuras Anidadas Dinámicas (Subsistemas del Satélite):
|
||||
* Crea una estructura principal (por ejemplo, MisionEspacial) que contenga
|
||||
* un puntero a un arreglo dinámico de subestructuras (representando varios
|
||||
* subsistemas como energía, propulsión y comunicación). Asegúrate de
|
||||
* implementar un protocolo estricto de liberación en orden inverso
|
||||
* (primero las subestructuras internas y sus recursos, luego el arreglo
|
||||
* principal) para evitar fugas de memoria (memory leaks) críticas en órbita.
|
||||
*
|
||||
* REQUISITOS TÉCNICOS:
|
||||
* - Uso obligatorio de las funciones de <stdlib.h> (malloc, realloc, free).
|
||||
* - Validación de punteros (verificar que no sean NULL tras cada reserva).
|
||||
* - Código limpio, modularizado en funciones y bien comentado.
|
||||
* ========================================================================= */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct{
|
||||
size_t size;
|
||||
uint8_t *datos;
|
||||
}TelemetryFile;
|
||||
|
||||
typedef struct{
|
||||
TelemetryFile base;
|
||||
size_t offset;
|
||||
}TelemetryArray;
|
||||
|
||||
typedef struct{
|
||||
int n_chanels;
|
||||
int* chanels;
|
||||
TelemetryFile* telemetry_file;
|
||||
TelemetryArray telemetry_array;
|
||||
}ProgramData;
|
||||
|
||||
|
||||
void print_menu(ProgramData *);
|
||||
void print_data(ProgramData *);
|
||||
void get_nchanels(ProgramData *);
|
||||
void get_chanels(ProgramData *);
|
||||
|
||||
void get_telemetry_file(ProgramData *);
|
||||
TelemetryFile* telemetry_file_create(size_t fs);
|
||||
void telemetry_file_free(ProgramData *);
|
||||
|
||||
void get_telemetry_data(ProgramData *);
|
||||
bool telemetry_array_is_full(ProgramData *);
|
||||
void telemetry_array_alloc(ProgramData *);
|
||||
void telemetry_array_free(ProgramData *);
|
||||
void telemetry_array_set(ProgramData *, uint8_t data);
|
||||
|
||||
void free_data(ProgramData*);
|
||||
void pause(void);
|
||||
|
||||
|
||||
int main(void){
|
||||
|
||||
ProgramData data = {
|
||||
.n_chanels = 0,
|
||||
.chanels = NULL,
|
||||
.telemetry_file = NULL,
|
||||
.telemetry_array = {
|
||||
.base = {
|
||||
.size = 0,
|
||||
.datos = NULL
|
||||
},
|
||||
.offset = 0
|
||||
}
|
||||
};
|
||||
|
||||
print_menu(&data);
|
||||
|
||||
free_data(&data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_menu(ProgramData* ref_data){
|
||||
|
||||
int option = 0;
|
||||
int exit = 0;
|
||||
|
||||
system("clear");
|
||||
printf("MENU DE OPCIONES\n");
|
||||
printf("\t 1- Cargar canales\n");
|
||||
printf("\t 2- Mostrar Datos\n");
|
||||
printf("\t 3- Crear archivo de telemetría\n");
|
||||
printf("\t 4- Recibir telemetria\n");
|
||||
printf("\t 5- Salir\n");
|
||||
|
||||
scanf("%d", &option);
|
||||
|
||||
switch (option) {
|
||||
case 1:
|
||||
get_nchanels(ref_data);
|
||||
get_chanels(ref_data);
|
||||
break;
|
||||
case 2:
|
||||
print_data(ref_data);
|
||||
break;
|
||||
case 3:
|
||||
get_telemetry_file(ref_data);
|
||||
break;
|
||||
case 4:
|
||||
get_telemetry_data(ref_data);
|
||||
break;
|
||||
case 5:
|
||||
exit = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!exit){
|
||||
print_menu(ref_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void get_telemetry_data(ProgramData *ref_data){
|
||||
system("clear");
|
||||
printf("RECEPCION DE TELEMETRIA\n");
|
||||
uint8_t read_data;
|
||||
|
||||
do{
|
||||
printf("\nIngresar valor (0 para terminar):");
|
||||
scanf("%" SCNu8, &read_data);
|
||||
|
||||
//printf("Se ha leido: %" SCNu8 "\n", read_data);
|
||||
|
||||
if(read_data > 0){
|
||||
telemetry_array_set(ref_data, read_data);
|
||||
}
|
||||
|
||||
}while(read_data > 0);
|
||||
}
|
||||
|
||||
bool telemetry_array_is_full(ProgramData *ref_data){
|
||||
|
||||
uint8_t* start_add = ref_data->telemetry_array.base.datos;
|
||||
|
||||
if(start_add == NULL){
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t* end_add = start_add + ref_data->telemetry_array.base.size;
|
||||
uint8_t* test_add = start_add + ref_data->telemetry_array.offset;
|
||||
return test_add >= (end_add);
|
||||
}
|
||||
|
||||
void telemetry_array_alloc(ProgramData *ref_data){
|
||||
//Si esta vacio reserva espacio para uno.
|
||||
if(ref_data->telemetry_array.base.datos == NULL){
|
||||
ref_data->telemetry_array.base.datos = malloc(sizeof(uint8_t));
|
||||
if(ref_data->telemetry_array.base.datos == NULL){
|
||||
perror("Error asignando memoria para streaming de telemetria.");
|
||||
exit(1);
|
||||
}
|
||||
ref_data->telemetry_array.base.size = 1;
|
||||
ref_data->telemetry_array.offset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* result = realloc(ref_data->telemetry_array.base.datos, ref_data->telemetry_array.base.size * 2);
|
||||
|
||||
if(result == NULL){
|
||||
perror("Error reasignando memoria para streaming de telemetria.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ref_data->telemetry_array.base.datos = result;
|
||||
ref_data->telemetry_array.base.size *= 2;
|
||||
|
||||
printf("La nueva capacidad es: %zu \n", ref_data->telemetry_array.base.size);
|
||||
}
|
||||
|
||||
void telemetry_array_free(ProgramData *ref_data){
|
||||
if(ref_data->telemetry_array.base.datos == NULL){
|
||||
free(ref_data->telemetry_array.base.datos);
|
||||
ref_data->telemetry_array.base.datos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void telemetry_array_set(ProgramData *ref_data, uint8_t data){
|
||||
if(telemetry_array_is_full(ref_data)){
|
||||
printf("Esta lleno, vamos a agrandar \n");
|
||||
telemetry_array_alloc(ref_data);
|
||||
}
|
||||
|
||||
*(ref_data->telemetry_array.base.datos + ref_data->telemetry_array.offset) = data;
|
||||
ref_data->telemetry_array.offset += 1;
|
||||
}
|
||||
|
||||
|
||||
void get_telemetry_file(ProgramData *ref_data){
|
||||
|
||||
size_t fs;
|
||||
|
||||
system("clear");
|
||||
|
||||
printf("CREAR ARCHIVO DE TELEMETRIA\n");
|
||||
printf("\tEnter de size in bytes:");
|
||||
scanf("%zu", &fs);
|
||||
|
||||
telemetry_file_free(ref_data);
|
||||
ref_data->telemetry_file = telemetry_file_create(fs);
|
||||
|
||||
}
|
||||
|
||||
void telemetry_file_free(ProgramData *ref_data){
|
||||
if(ref_data->telemetry_file != NULL){
|
||||
if(ref_data->telemetry_file->datos != NULL){
|
||||
free(ref_data->telemetry_file->datos);
|
||||
ref_data->telemetry_file->datos = NULL;
|
||||
}
|
||||
free(ref_data->telemetry_file);
|
||||
ref_data->telemetry_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TelemetryFile* telemetry_file_create(size_t fs){
|
||||
TelemetryFile* telemetry_file = malloc(sizeof(TelemetryFile));
|
||||
|
||||
if(telemetry_file == NULL){
|
||||
perror("Error creating telemetry file.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
telemetry_file->size = fs;
|
||||
telemetry_file->datos = malloc(sizeof(uint8_t)*fs);
|
||||
|
||||
if(telemetry_file->datos == NULL){
|
||||
free(telemetry_file);
|
||||
telemetry_file = NULL;
|
||||
perror("Error allocating memory for the buffer to telemetry file.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return telemetry_file;
|
||||
|
||||
}
|
||||
|
||||
void get_nchanels(ProgramData* ref_data){
|
||||
system("clear");
|
||||
int n_chanels = 0;
|
||||
printf("Cantidad de canales: ");
|
||||
scanf("%d", &n_chanels);
|
||||
|
||||
ref_data->n_chanels = n_chanels;
|
||||
|
||||
}
|
||||
|
||||
void get_chanels(ProgramData* ref_data){
|
||||
if(ref_data->chanels != NULL){
|
||||
free(ref_data->chanels);
|
||||
ref_data->chanels = NULL;
|
||||
}
|
||||
ref_data->chanels = malloc(sizeof(int)*ref_data->n_chanels);
|
||||
if(ref_data->chanels == NULL){
|
||||
perror("No se pudo reservar memoria para los canales.");
|
||||
exit(1);
|
||||
}
|
||||
for(int i=0; i < ref_data->n_chanels; i++){
|
||||
int chanel;
|
||||
printf("Frecuacia en Mhz del canal%d:", i);
|
||||
scanf("%d", &chanel);
|
||||
*(ref_data->chanels + i) = chanel;
|
||||
}
|
||||
}
|
||||
|
||||
void print_data(ProgramData* ref_data){
|
||||
system("clear");
|
||||
printf("DATOS DEL PROGRAMA\n");
|
||||
printf("Cantidad de canales: %d\n", ref_data->n_chanels);
|
||||
|
||||
for (int i=0; i < ref_data->n_chanels; i++){
|
||||
printf("\t CH %d Mhz\n", *(ref_data->chanels + i));
|
||||
}
|
||||
|
||||
if(ref_data->telemetry_file != NULL){
|
||||
printf("Archivo de telemetria creado. Size: %zu bytes.\n", ref_data->telemetry_file->size);
|
||||
}
|
||||
|
||||
printf("Datos de telemetria: ");
|
||||
for(size_t i=0; i < ref_data->telemetry_array.offset; i++){
|
||||
printf("%" SCNu8 ", ", *(ref_data->telemetry_array.base.datos + i));
|
||||
}
|
||||
if(ref_data->telemetry_array.base.size == 0){
|
||||
printf("No hay datos.");
|
||||
}
|
||||
printf("\n");
|
||||
pause();
|
||||
}
|
||||
|
||||
void free_data(ProgramData* ref_data){
|
||||
if(ref_data->chanels){
|
||||
free(ref_data->chanels);
|
||||
}
|
||||
telemetry_file_free(ref_data);
|
||||
telemetry_array_free(ref_data);
|
||||
}
|
||||
|
||||
void pause(void){
|
||||
// 1. Limpiamos el búfer por si quedó algún caracter pendiente del scanf anterior
|
||||
int c;
|
||||
while ((c = getchar()) != '\n' && c != EOF);
|
||||
// 2. Mostramos el mensaje y esperamos a que el usuario presione Enter de verdad
|
||||
printf("Presione Enter para continuar...\n");
|
||||
getchar();
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void swap(char **, char**);
|
||||
void swap_int(int *, int *);
|
||||
|
||||
int main(void){
|
||||
char *s1 = "Hola";
|
||||
char *s2 = "Mundo";
|
||||
int n1 = 10;
|
||||
int n2 = 20;
|
||||
swap(&s1, &s2);
|
||||
swap_int(&n1, &n2);
|
||||
printf("s1: %s s2: %s\n", s1, s2);
|
||||
printf("n1: %d n2: %d\n", n1, n2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void swap(char **s1, char **s2){
|
||||
char *aux = *s1;
|
||||
*s1 = *s2;
|
||||
*s2 = aux;
|
||||
}
|
||||
|
||||
void swap_int(int* n1, int* n2){
|
||||
int aux = *n1;
|
||||
*n1 = *n2;
|
||||
*n2 = aux;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
/* ============================================================================
|
||||
* Ejercicio: Modificación de un Puntero a través de un Puntero a Puntero (int **)
|
||||
* ============================================================================
|
||||
* Objetivo:
|
||||
* Comprender el uso de punteros a punteros para modificar la dirección a la
|
||||
* que apunta un puntero original dentro de una función (pasaje por referencia).
|
||||
*
|
||||
* Descripción:
|
||||
* Escribe un programa en C que cumpla con los siguientes requisitos:
|
||||
*
|
||||
* 1. Define dos variables enteras, por ejemplo: `int x = 10;` e `int y = 20;`.
|
||||
* 2. Declara un puntero simple a entero, por ejemplo: `int *ptr = &x;`.
|
||||
* 3. Crea una función llamada `cambiar_puntero` que reciba un puntero a puntero
|
||||
* (`int **p_ref`) y la dirección de otra variable entera (`int *nueva_dir`).
|
||||
* La función debe actualizar el puntero original para que ahora apunte a
|
||||
* esa nueva dirección (`*p_ref = nueva_dir;`).
|
||||
* 4. En la función `main`, imprime el valor al que apunta `ptr` antes de llamar
|
||||
* a la función.
|
||||
* 5. Llama a `cambiar_puntero` pasando la dirección de `ptr` (`&ptr`) y la
|
||||
* dirección de `y` (`&y`).
|
||||
* 6. Vuelve a imprimir el valor al que apunta `ptr` después de la llamada para
|
||||
* verificar que ahora apunta a `y` (su valor debe ser 20).
|
||||
*
|
||||
* Restricciones:
|
||||
* - Debes utilizar obligatoriamente el operador de indirección doble (**).
|
||||
* - No olvides validar los conceptos de memoria y desreferenciación.
|
||||
* ============================================================================ */
|
||||
#include <stdio.h>
|
||||
|
||||
void cambiar_puntero(int**, int*);
|
||||
|
||||
int main(void){
|
||||
|
||||
int x = 20, y = 30;
|
||||
int* ptr = &x;
|
||||
|
||||
printf("contenido de ptr = %d \n", *ptr);
|
||||
|
||||
cambiar_puntero(&ptr, &y);
|
||||
|
||||
|
||||
printf("contenido de ptr = %d\n", *ptr);
|
||||
|
||||
}
|
||||
|
||||
void cambiar_puntero(int** ptr, int *address){
|
||||
*ptr = address;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user