I've having a segmentation fault error in my program. This is the code: for first, I've a struct:
struct Slave
{
char **all_samples;
int number_of_samples;
char **last_samples;
int **RSSI;
int *AGC;
int *AUTH;
};
Then I've a function: (debbugging I'm sure that the segmentation fault occurs when I call RSSI function).
all_samples and last_samples are 2 arrays. the first contains N string (N is variable), while the second surely contains 4 strings.
struct Slave *read_slaves_file(char *file_path, char *slave)
{
...
char **all_samples = malloc(N * sizeof(char *));
char **last_samples = malloc(4 * sizeof(char *));
struct Slave *slave_ptr = malloc(sizeof(struct Slave *));
slave_ptr->last_samples = last_samples;
slave_ptr->all_samples = all_samples;
slave_ptr->number_of_samples = i;
slave_ptr->RSSI = RSSI(slave_ptr->last_samples);
return slave_ptr;
}
and this is RSSI function:
it simply parse a string to extract the number after the -RSSI word. For example:
2022-10-14 8:51:17:708 -IP 192.168.101.11 -RSSI 88367 -AGC 429496720 -AUTH 0
It extracts 88367. It works on 4 strings like this one.
int **RSSI(char **last_samples)
{
int **rssi_value = malloc(sizeof(int *) * 128);
char string[128];
const char s[16] = " ";
char *token;
int i;
for (int k = 0; k < 4; k++)
{
strcpy(string, last_samples[k]);
token = strtok(string, s);
i = 0;
while (token != NULL)
{
if (i == 5)
{
rssi_value[k] = atoi(token);
}
i++;
token = strtok(NULL, s);
}
}
return rssi_value;
}
Into main.c:
#include "lib.h"
int main()
{
while (true)
{
...
struct Slave *slave_1 = read_slaves_file(FILE_PATH, SLAVE_1);
free(slave_1->last_samples);
free(slave_1->all_samples);
free(slave_1->RSSI);
free(slave_1);
usleep(1000*1000);
}
return 0;
}
This memory allocation is already invalid
struct Slave *slave_ptr = malloc(sizeof(struct Slave *));
^^^^^^^^^^^^^^
You need to write
struct Slave *slave_ptr = malloc(sizeof(struct Slave));
^^^^^^^^^^^^^^
or
struct Slave *slave_ptr = malloc(sizeof( *slave_ptr ));
^^^^^^^^^^^^^
Also in this for loop
for (int k = 0; k < 4; k++)
{
strcpy(string, last_samples[k]);
//...
the call of strcpy uses uninitialized pointers last_samples[k].
And this statement
rssi_value[k] = atoi(token);
is also incorrect. There is an attempt to initialize a pointer with an integer.
Related
I am trying to create a dynamic array of Clients, but i am not succeding. This is my code. When i run this code the output is
3
� H
3
4332
3
8939
I think it's printing memory stuff, however i don't know why. I put my code down here
int client_counter = 0;
typedef struct client
{
char *pid;
char *message;
}Client;
void store (Client * client_array, char *buf)
{
Client c;
c.pid = strdup (strtok (buf, ":"));
c.message = strdup (strtok (NULL, "\0"));
client_array[client_counter++] = c;
}
int main () {
Client* client_array = malloc (sizeof (struct client));
char buf1[50] = { "1245:message" };
store (client_array, buf1);
char buf2[50] = { "4332:message" };
store (client_array, buf2);
char buf3[50] = { "8939:message" };
store (client_array, buf3);
for (int i = 0; i < client_counter; i++)
{
printf ("%d\n", client_counter);
printf ("%s\n", client_array[i].pid);
}
return 0;
}
I already tried do use this:
client_array = realloc(client_array, sizeof(struct client) * (client_counter + 1));
in store function right after this line.
client_array[client_counter++] = c;
But it's not working too.
You need to allocate extra memory if there's not enough space. Right now, you allocate enough for one, but you try to access three.
Don't forget to return the pointer of the new memory block back to main! In the following, this is done by passing a pointer to the caller's pointer. store modifies the caller's pointer via the passed pointer.
// Sets errno and returns 0 on error.
int store(Client ** client_array_ptr, char *buf) {
Client* new_client_array = realloc(*client_array_ptr, sizeof(Client) * (client_counter + 1));
if (!new_client_array)
return 0;
*client_array_ptr = new_client_array;
// ...
new_client_array[client_counter++] = c;
return 1;
}
int main() {
Client* client_array = NULL;
// ...
if (!store(&client_array, buf1)) {
perror("malloc");
exit(1);
}
// ...
if (!store(&client_array, buf2)) {
perror("malloc");
exit(1);
}
// ...
free(client_array);
return 0;
}
The original code does out-of-range access because it is trying to store multiple data in a buffer which is allocated for only one element.
To use realloc(), you have to note that arguments of functions in C are copies of what are passed. Modifying arguments inside callee function do not affect what is passed in caller. You should pass pointers to what should be modified to have functions modify caller's local things.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int client_counter = 0;
typedef struct client
{
char *pid;
char *message;
}Client;
void store (Client ** client_array, char *buf)
{
Client c;
c.pid = strdup (strtok (buf, ":"));
c.message = strdup (strtok (NULL, "\0"));
*client_array = realloc(*client_array, sizeof(struct client) * (client_counter + 1));
(*client_array)[client_counter++] = c;
}
int main () {
Client* client_array = malloc (sizeof (struct client));
char buf1[50] = { "1245:message" };
store (&client_array, buf1);
char buf2[50] = { "4332:message" };
store (&client_array, buf2);
char buf3[50] = { "8939:message" };
store (&client_array, buf3);
for (int i = 0; i < client_counter; i++)
{
printf ("%d\n", client_counter);
printf ("%s\n", client_array[i].pid);
}
return 0;
}
I would do it a bit different way.
typedef struct
{
char *pid;
char *message;
}client_TypeDef;
typedef struct
{
size_t size;
client_TypeDef clients[];
}clients_TypeDef;
clients_TypeDef *add(clients_TypeDef *clients, const char *pid, const char *message)
{
size_t newsize = clients ? clients -> size + 1 : 1;
client_TypeDef client = {.pid = strdup(pid), .message = strdup(message)};
if(client.pid && client.message)
{
clients = realloc(clients, sizeof(*clients) + newsize * sizeof(clients -> clients[0]));
if(clients)
{
clients -> size = newsize;
clients -> clients[newsize - 1] = client;
}
}
else
{
free(client.pid);
free(client.message);
clients = NULL;
}
return clients;
}
I've defined a struct to represent strings and want to make a list from this string-structs. I've coded a function toString, which gets a char pointer and the result is such a string-struct. I've coded a function toList, which gets a pointer of char pointer, makes strings from these char pointers and concatenate these to a list of strings.
Now I want to use these, but I always get this stack error 0 [main] stringL 1123 cygwin_exception::open_stackdumpfile: Dumping stack trace to stringL.exe.stackdump. Could the problem be the assignment with makro? Not even the debug output 0, 1, 2, 3 is printed. I'm thankful for some help.
Code:
#include<stdio.h>
#include<stdlib.h>
#define EMPTYLIST NULL
#define ISEMPTY(l) ((l) == EMPTYLIST)
#define TAIL(l) ((l)->next)
#define HEAD(l) ((l)->str)
typedef struct {
char *str;
unsigned int len;
} String;
typedef struct ListNode *StringList;
struct ListNode {
String str;
StringList next;
};
String toString (char *cstr) {
String res = {NULL, 0};
res.str = malloc(sizeof(char));
char *ptr = res.str;
while(*cstr) {
*ptr++ = *cstr++;
res.str = realloc(res.str, sizeof(char) * (res.len +2));
res.len++;
}
*ptr = '\0';
return res;
}
StringList toList (char **cstrs, unsigned int sc){
if(sc > 0) {
StringList res = malloc(sizeof(*res));
HEAD(res) = toString(*cstrs);
TAIL(res) = toList(cstrs+1, sc+1);
}
return EMPTYLIST;
}
int main() {
printf("0");
char **strs = malloc(sizeof(**strs) *2);
unsigned int i = 0;
char *fst = "Der erste Text";
char *snd = "Der zweite Text";
printf("1");
StringList res = toList(strs, 2);
StringList lstPtr = res;
strs[0] = malloc(sizeof(char) * 15);
strs[1] = malloc(sizeof(char) * 16);
printf("2");
while(*fst) {
strs[0][i] = *fst++;
i++;
}
printf("3");
i = 0;
while(*snd) {
strs[1][i] = *snd++;
i++;
}
printf("Liste: \n");
for(i = 0; i < 2; i++){
printf("Text %d: %s\n", i, HEAD(lstPtr++));
}
return 0;
}
After this statement
res.str = realloc(res.str, sizeof(char) * (res.len +2));
the value stored in the pointer res.str can be changed. As a result the value stored in the pointer ptr after its increment
*ptr++ = *cstr++;
can be invalid and does not point to a place in the reallocated memory.
Here is my problem: I have to make this program for school and I spent the last hour debugging and googling and haven't found an answer.
I have an array of structures in my main and I want to give that array to my function seteverythingup (by call by reference) because in this function a string I read from a file is split up, and I want to write it into the structure but I always get a SIGSEV error when strcpy with the struct array.
This is my main:
int main(int argc, char *argv[])
{
FILE* datei;
int size = 10;
int used = 0;
char line[1000];
struct raeume *arr = (raeume *) malloc(size * sizeof(raeume*));
if(arr == NULL){
return 0;
}
if(argc < 2){
return 0;
}
datei = fopen(argv[1], "rt");
if(datei == NULL){
return 0;
}
fgets(line,sizeof(line),datei);
while(fgets(line,sizeof(line),datei)){
int l = strlen(line);
if(line[l-1] == '\n'){
line[l-1] = '\0';
}
seteverythingup(&line,arr,size,&used);
}
ausgabeunsortiert(arr,size);
fclose(datei);
return 0;
}
and this is my function:
void seteverythingup(char line[],struct raeume *arr[], int size,int used)
{
char *token,raumnummer[5],klasse[6];
int tische = 0;
const char c[2] = ";";
int i=0;
token = strtok(line, c);
strcpy(raumnummer,token);
while(token != NULL )
{
token = strtok(NULL, c);
if(i==0){
strcpy(klasse,token);
}else if(i==1){
sscanf(token,"%d",&tische);
}
i++;
}
managesize(&arr[size],&size,used);
strcpy(arr[used]->number,raumnummer);
strcpy(arr[used]->klasse,klasse);
arr[used]->tische = tische;
used++;
}
Edit: Since there is more confusion I wrote a short program that works out the part you are having trouble with.
#include <cstdlib>
struct raeume {
int foo;
int bar;
};
void seteverythingup(struct raeume *arr, size_t len) {
for (size_t i = 0; i < len; ++i) {
arr[i].foo = 42;
arr[i].bar = 53;
}
}
int main() {
const size_t size = 10;
struct raeume *arr = (struct raeume*) malloc(size * sizeof(struct raeume));
seteverythingup(arr, size);
return 0;
}
So basically the signature of your functions is somewhat odd. Malloc returns you a pointer to a memory location. So you really dont need a pointer to an array. Just pass the function the pointer you got from malloc and the function will be able to manipulate that region.
Original Answer:
malloc(size * sizeof(raeume*));
This is probably the part of the code that gives you a hard time. sizeof returns the size of a type. You ask sizeof how many bytes a pointer to you raeume struct requires. what you probably wanted to do is ask for the size of the struct itself and allocate size times space for that. So the correct call to malloc would be:
malloc(size * sizeof(struct raeume));
How would I assign the value from strtok() to an array that's in a struct? Inside my struct I have char *extraRoomOne and in my main I have:
while (token!= NULL)
{
token = strtok(NULL, " ");
certainRoom.extraRoomOne[counter] = token;
}
Compiler is telling me to dereference it, but when I do I get a seg fault.
typedef struct room{
char *extraRoomOne;
}room;
In main, all I had was `room certainRoom;
Edit: changed char *extraRoomOne to char **extraRoomOne
Now I have:
token = strtok(NULL," ");
certainRoom.extraRoomOne = realloc(certainRoom.extraRoomOne,(counter + 1) * sizeof(char *));
certainRoom.extraRoomOne[counter] = malloc(strlen(token)+1);
strcpy(certainRoom.extraRoomOne[counter],token);`
Is this the correct way of realloc and malloc? I increment the counter below each time as well
You should not do that assignment because strtok() returns a pointer to the string you passed in the first call and it will change it in subsequent calls, and the '\0' terminator can be moved by strtok() so the pointer will point to a different string at the end, but instead you can copy the string first allocating space for it with malloc() and then with strcpy()
size_t length;
length = strlen(token);
certainRoom.extraRoomOne = malloc(1 + length);
if (certainRoom.extraRoomOne != NULL)
strcpy(certainRoom.extraRoomOne, token);
you should remember to include string.h.
And if what you really want is to capture more than just one token, which would explain the while loop, you could do it this way
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct room{
char **tokens;
size_t count;
} room;
room
tokenizeString(char *string)
{
char *token;
room instance;
instance.tokens = NULL;
instance.count = 0;
token = strtok(string, " ");
while (token != NULL)
{
void *pointer;
size_t length;
pointer = realloc(instance.tokens, (1 + instance.count) * sizeof(char *));
if (pointer == NULL)
{
size_t i;
for (i = 0 ; i < instance.count ; ++i)
free(instance.tokens[i]);
free(instance.tokens);
instance.tokens = NULL;
instance.count = 0;
return instance;
}
instance.tokens = pointer;
length = strlen(token);
instance.tokens[instance.count] = malloc(1 + length);
if (instance.tokens[instance.count] != NULL)
strcpy(instance.tokens[instance.count], token);
instance.count += 1;
token = strtok(NULL, " ");
}
return instance;
}
int
main(int argc, char **argv)
{
room certainRoom;
size_t i;
if (argc < 1) /* invalid number of arguments */
return -1;
certainRoom = tokenizeString(argv[1]);
for (i = 0 ; i < certainRoom.count ; ++i)
{
printf("%s\n", certainRoom.tokens[i]);
/* we are done working with this token, release it */
free(certainRoom.tokens[i]);
}
/* all tokens where released, now released the main container,
* note, that this only contained the pointers, the data was
* in the space pointed to by these pointers. */
free(certainRoom.tokens);
return 0;
}
IN my code, I have a random character that appears when I send a char array through a function, like so:
struct TokenizerT_ { //Defintion of the struct
char * sep;
char * toks;
};
TokenizerT *TKCreate(char *separators, char *ts) {
TokenizerT * inu = malloc(sizeof(*inu));
inu->toks = malloc(sizeof(char)); //Initialize char array that will store the tokens
strcpy(inu->toks, hr);
return inu;
}
.......
best = "sein";
printf("%s\n", best);
char * rondo = malloc(sizeof(char));
printf("%s\n", rondo);
TokenizerT * Ray = TKCreate(copy, rondo); /
printf("%s\n", Ray->toks);
For the last bit, the printed out values are as follows:
sein
sein
sein?
Why is the question mark appearing? This is usually a random character and not always a question mark.
Edit: Full code, really desperate
struct TokenizerT_ { //Defintion of the struct
char * sep;
char * toks;
};
char nulines[10] = "ntvbrfa\\\""; //for the arguments with backslashes
char resp[37] = "0x0a0x090x0b0x080x0d0x0c0x070x5c0x22";
typedef struct TokenizerT_ TokenizerT;
TokenizerT *TKCreate(char *separators, char *ts) {
if (ts==NULL) { //If there are no tokens to be parsed (empty entry)
return NULL;
}int lim = 1;
char yr[strlen(separators)]; //Initializes delimitors
yr[0] = *separators;
if(strlen(separators)>0){
int h =1;
char zmp = *(separators+h);
for(h=1; h<strlen(separators); h++){
zmp = *(separators+h);
int z=0;
for (z=0; z<lim; z++) {
if (zmp==yr[z]) {
z=-1;
break;
}
}
if(z>-1){
yr[lim] = zmp;
lim++;}
else{
continue;
} //yr is local variable that contains delimitors
}}
TokenizerT * inu = malloc(sizeof(*inu)); //Creates TokenizerT
inu->sep = malloc((int)strlen(yr)*sizeof(char));
strcpy(inu->sep, yr);
char hr [strlen(ts)];
lim = 0; int q = 0; int wy=0;
for(q=0; q<strlen(ts); q++){
if(ts[q]=='\\'){
q++;
for(wy = 0; wy<strlen(nulines); wy++){
if (nulines[wy]==ts[q]) {
hr[lim] = '['; hr[++lim] = '0'; hr[++lim] = 'x'; hr[++lim] = resp[wy*4+2];
hr[++lim] = resp[wy*4+3];
hr[++lim] = ']'; lim++;
break;
}
}
continue;
}
else{
hr[lim] = ts[q];
lim++;
}
}
inu->toks = (char *)malloc(sizeof(char) * strlen(hr) + 1);
strcpy(inu->toks, hr); //Makes copy
return inu;
}
void TKDestroy(TokenizerT *tk) {
free(tk->toks); //Free Memory associated with the token char array
free(tk->sep); //Free Memory associated with the delimitor char array
free(tk); //Free Memory associated with the tokenizer
}
char *TKGetNextToken(TokenizerT *tk) {
char * stream = tk->toks;
char * dels = tk->sep;
/*The following two lines intialize the char array to be printed
as well as the integers to be used in the various loops*/
char * temps = malloc(sizeof(char)); int g = 0;
int z = 0, x= 0, len = 0;
if (strlen(dels)==0) {
return stream;
}
for(z = 0; z<strlen(stream); z++){
char b = *(stream+z);
for(x = 0; x<strlen(dels); x++){
len = (int)strlen(temps);
char c = *(dels+x);
if(c==b){ //Here, the current character is a delimitor
g = -1;
break;
}
}
if (g==-1) { //If delimitor, then return the current token
return temps;
}
*(temps+len) = b;
}
len = (int)strlen(temps);
*(temps+len) = '\0'; //Returns the string with the null character ending it
return temps;
}
void TKN(TokenizerT * tin, int sum){
char * tmp = TKGetNextToken(tin);
char * copy = malloc(sizeof(char));
strcpy(copy, tin->sep);
int difference = (int)strlen(tmp)+1;
sum = sum-difference;
char * best = malloc(sizeof(char));
strcpy(best, tin->toks + difference);
if((int)strlen(tmp)>0){
printf("%s\n", tmp);
}
TKDestroy(tin);
tin = TKCreate(copy, best);
while(sum>0){
tmp = TKGetNextToken(tin);
if((int)strlen(tmp)>0){
printf("%s\n", tmp);
}
difference = (int)strlen(tmp)+1;
sum = sum-difference;
free(best);
best = malloc(sizeof(char));
strcpy(best, tin->toks + difference);
TKDestroy(tin);
tin = TKCreate(copy, best);
}
free(copy);
free(best);
free(tmp);
TKDestroy(tin); //Freeing up memory associated with the Tokenizer
return;
}
int main(int argc, char **argv) {
if(argc<2){
printf("%s\n", "Not enough arguments");
return 0;
}
else if(argc>3){
printf("%s\n", "Too many arguments");
return 0;
}
else{
char * arr = argv[1]; //Represents delimitors
char * y = argv[2]; //Represents string to be tokenized
TokenizerT * jer = TKCreate(arr, y); //Create and initialize tokenizer
//printf("%s\n", jer->toks);
TKN(jer, (int)strlen(jer->toks));
}
return 0;
}
In most of your malloc, you don't only allocate for one character:
malloc(sizeof(char))
while you should write:
malloc(sizeof(char) * n + 1)
Where n is the length of string that you want and +1 is for the terminating null character. You are seeing the random character it is because both C and C++ use null character as the termination for string datatype and by not allocating correctly, it starts for read until it gets to null.
struct TokenizerT_ { //Defintion of the struct
char * sep;
char * toks;
};
char nulines[10] = "ntvbrfa\\\""; //for the arguments with backslashes
char resp[37] = "0x0a0x090x0b0x080x0d0x0c0x070x5c0x22";
typedef struct TokenizerT_ TokenizerT;
TokenizerT *TKCreate(char *separators, char *ts) {
if (ts==NULL) { //If there are no tokens to be parsed (empty entry)
return NULL;
}int lim = 1;
char yr[strlen(separators)]; //Initializes delimitors
yr[0] = *separators;
if(strlen(separators)>0){
int h =1;
char zmp = *(separators+h);
for(h=1; h<strlen(separators); h++){
zmp = *(separators+h);
int z=0;
for (z=0; z<lim; z++) {
if (zmp==yr[z]) {
z=-1;
break;
}
}
if(z>-1){
yr[lim] = zmp;
lim++;}
else{
continue;
} //yr is local variable that contains delimitors
}}
TokenizerT * inu = (TokenizerT *)malloc(sizeof(*inu)); //Creates TokenizerT
inu->sep = (char *)malloc((int)strlen(yr)*sizeof(char));
strcpy(inu->sep, yr);
char hr [strlen(ts)];
lim = 0; int q = 0; int wy=0;
for(q=0; q<strlen(ts); q++){
if(ts[q]=='\\'){
q++;
for(wy = 0; wy<strlen(nulines); wy++){
if (nulines[wy]==ts[q]) {
hr[lim] = '['; hr[++lim] = '0'; hr[++lim] = 'x'; hr[++lim] = resp[wy*4+2];
hr[++lim] = resp[wy*4+3];
hr[++lim] = ']'; lim++;
break;
}
}
continue;
}
else{
hr[lim] = ts[q];
lim++;
}
}
inu->toks = (char *)malloc(sizeof(char) * strlen(hr) + 1);
strcpy(inu->toks, hr); //Makes copy
return inu;
}
void TKDestroy(TokenizerT *tk) {
free(tk->toks); //Free Memory associated with the token char array
free(tk->sep); //Free Memory associated with the delimitor char array
free(tk); //Free Memory associated with the tokenizer
}
char *TKGetNextToken(TokenizerT *tk) {
char * stream = tk->toks;
char * dels = tk->sep;
/*The following two lines intialize the char array to be printed
as well as the integers to be used in the various loops*/
char * temps = (char *)malloc(sizeof(char)); int g = 0;
int z = 0, x= 0, len = 0;
if (strlen(dels)==0) {
return stream;
}
for(z = 0; z<strlen(stream); z++){
char b = *(stream+z);
for(x = 0; x<strlen(dels); x++){
len = (int)strlen(temps);
char c = *(dels+x);
if(c==b){ //Here, the current character is a delimitor
g = -1;
break;
}
}
if (g==-1) { //If delimitor, then return the current token
return temps;
}
*(temps+len) = b;
}
len = (int)strlen(temps);
*(temps+len) = '\0'; //Returns the string with the null character ending it
return temps;
}
void TKN(TokenizerT * tin, int sum){
char * tmp = TKGetNextToken(tin);
char * copy = (char *)malloc(sizeof(char));
strcpy(copy, tin->sep);
int difference = (int)strlen(tmp)+1;
sum = sum-difference;
char * best = (char *)malloc(sizeof(char));
strcpy(best, tin->toks + difference);
if((int)strlen(tmp)>0){
printf("%s\n", tmp);
}
TKDestroy(tin);
tin = TKCreate(copy, best);
while(sum>0){
tmp = TKGetNextToken(tin);
if((int)strlen(tmp)>0){
printf("%s\n", tmp);
}
difference = (int)strlen(tmp)+1;
sum = sum-difference;
free(best);
best = (char *)malloc(sizeof(char));
strcpy(best, tin->toks + difference);
TKDestroy(tin);
tin = TKCreate(copy, best);
}
free(copy);
free(best);
free(tmp);
TKDestroy(tin); //Freeing up memory associated with the Tokenizer
return;
}
int main(int argc, char **argv) {
if(argc<2){
printf("%s\n", "Not enough arguments");
return 0;
}
else if(argc>3){
printf("%s\n", "Too many arguments");
return 0;
}
else{
char * arr = argv[1]; //Represents delimitors
char * y = argv[2]; //Represents string to be tokenized
TokenizerT * jer = TKCreate(arr, y); //Create and initialize tokenizer
//printf("%s\n", jer->toks);
TKN(jer, (int)strlen(jer->toks));
}
return 0;
}
char * rondo = malloc(sizeof(char));
printf("%s\n", rondo);
is a UB(Undefined behaviour) condition.
This is what you are doing:
free store(heap) -> allocate memory of size char(usually 1 byte) and get the address of that location and store it(address) in rondo.
so when you dereference rondo i.e *rondo you can legally only access the location that is of the size of char accessing anything next to it or near it is illegal.
so in printf("%s\n", rondo); what you do is tell printf that what pointer you give is a pointer to string and so print till you get a \0(NULL) character. but you did not actually do that. which means printf is actually accessing memory that was not allocated. what you saw is out of pure luck(or rather unfortunate).
you can only do this
printf("%c\n", *rondo); but even before this you have to initialize for e.g
char * rondo = malloc(sizeof(char));
*rondo = 'K';
printf("%c\n",*rondo);
but I bet you dint mean that you would have meant
char * rondo = malloc(sizeof(char)*no_of_characters_in_string+1);
where +1 is for the NULL character.
What characters you saw is not related to your program. you accessed someone else's memory(if it was allocated to some one else or OS's property).
Edit :
there is also a huge problem in you code. you are mallocing memory but are never freeing it. for small demo programs its ok(not really) but it definitely is very bad. please always associate a malloc with a free();
My advice get a good text book. it will tell you in more details about these things.