Hi.
I'm trying to figure out pointers and memory allocation in C. I've read quite a few explanations on the internet and have read in a few books that I've got, but I'm not so much smarter yet...
What I want do do is to create an array of five pointers to characters... I want to make it possible to assign a pointer to the params array tohrough the setParams function. I don't understand what I have not gotten, but there is certainly something. It seems like this works: - char * val1 = malloc(30);
-
free(val1);
but this doesn't: - char * val1 = malloc(30);
-
val1 = "Hei og hå!";
-
free(val1);
This seems logical to me, because the val1 variable is first instantiated with memory allocated and then set to "Hei og hå". I would assume the memory location returned from the malloc call would be lost, right?. The only walkaround for this problem as far as I have understood is to assign one char at the time and increase the pointer one position at the time and do
and then increase the pointer with val1++ for each letter. It sounds too complicated to be right.. Or is it like this? Another problem with that solution is that when I've moved the pointer a few positions I have lost the start position of the var and is no longer able to free the var because I don't have the right position.
If someone could straighten this out it would be awesome. I guess it's not so hard, but it is hard to get a grip on when you don't fully understand how the pointers work in C.
The code I'm trying to get to work is to large to post here I think, but if I get the idea on how to get the following piece of code right, much is done I think. NOTICE! If your going to compile it, compile with "-DDEBUG -DSOLO" to get the main method and the includes in the compile. - #ifdef DEBUG
-
#include <stdlib.h>
-
#include <stdio.h>
-
#endif
-
-
#include "bitwise.h"
-
-
int power(int num, int power) {
-
int i, res=1;
-
for(i=0; i<power; i++) {
-
res = res*num;
-
}
-
if(power==0)
-
return 1;
-
else
-
return res;
-
}
-
-
void setBit(unsigned char * map, int num, int val) {
-
if(val != getBit(map, num))
-
map[num/8] = (map[num/8]^power(2,7-(num%8)));
-
}
-
-
int getBit(unsigned char * map, int num) {
-
return ((map[num/8]>>(7-num)) & 1);
-
}
-
-
#ifdef SOLO
-
char * setParam(char * params[], unsigned char * map, int n, char * val) {
-
params[n] = val;
-
setBit(map, n, 1);
-
return params[n];
-
}
-
-
char * getParam(char * params[], unsigned char * map, int n) {
-
//if(getBit(map, n))
-
return params[n];
-
//else
-
// return NULL;
-
}
-
-
void removeParam(char * params[], unsigned char * map, int n) {
-
if(getBit(map, n)) {
-
printf("sletter: %x\n",params[n]);
-
free(params[n]);
-
setBit(map,n,0);
-
}
-
}
-
-
int paramUsed(char * params[], unsigned char * map, int n) {
-
return getBit(map, n);
-
}
-
-
int main() {
-
unsigned char status = 0;
-
char * params[5];
-
-
char * val1 = malloc(30);
-
val1 = "Hei og hå!";
-
-
printf("%s == %s\n",val1,setParam(¶ms[0], &status, 0, val1));
-
printf("%s\n",getParam(params, &status, 0));
-
printf("Used: %d\n",paramUsed(params, &status, 0));
-
removeParam(params, &status, 0);
-
printf("%s\n",getParam(params, &status, 0));
-
printf("Used: %d\n",paramUsed(params, &status, 0));
-
return 0;
-
}
-
#endif
Thanks in advance :)
K
11 4921 boxfish 469
Recognized Expert Contributor -
char * val1 = malloc(30);
-
val1 = "Hei og hå!";
-
free(val1);
-
Well hmm. I've only programmed in C++, so I'm not that familliar with malloc, but it seems you have to cast it to the data type you want; in this case, char*. As for copying a string into the allocated memory, you don't have to do it yourself; use the strcpy function. So the above code should be -
char * val1 = (char *)malloc(30);
-
strcpy(val1, "Hei og hå!");
-
free(val1);
-
Hope this helps.
-
char *val = malloc(30);
-
-
/* Advice: change that to: */
-
-
char *val = ( char * )calloc( 30, sizeof( char ) );
-
This allocates a space for 30 characters. It returns the initial address and stores it in the val pointer variable. So, val now points to that space.
Do not forget that strings in C are represented as sequences of characters in memory.
In this statement, val gets the initial address of the string, so now it points there...
When you do:
you have two problems:
-> First, you have lost where the space you allocated with malloc (or calloc) resides in memory and you cannot free it anymore.
-> Second, your program is most likely to get messy there.. free accepts a pointer earlier returned by a call to malloc, calloc or realloc.. In this case, the address of the string "..." is passed which might be in read-only memory (if your are lucky cause then you will get a assertion).
The correst way to do this is to copy the string to the newly allocated space...
hope i helped
oler1s 671
Recognized Expert Contributor
I'm not that familliar with malloc, but it seems you have to cast it to the data type you want
No. You don't have to cast malloc, and you probably don't want to, as it doesn't help but can hurt. Unless you want to compile under C++, C will implicitly do the cast.
krreks, you wouldn't write val1++. You can index it, such as val1[2]. You essentially have an array (dynamically allocated), and you can index that array, right? Think about arrays.
Also read http://c-faq.com/ on the relevant sections. The pointers vs. arrays section is particularly helpful.
Thanks a lot for great pointers to answers! I had been scratching my head for quite a few hours and it was great getting some answers that was not in-a-conversation-answers in a mailing list :) A few new questions arises and it would be wonderfull to get some answers to those as well.. 1. So the strcpy seems to be the way to go then. I wonder though why this works like it does: - char * val1 = (char *) malloc(5);
-
printf("%s\n",val1);
-
strcpy(val1, "test");
-
free(val1);
-
printf("%s\n",val1);
It seems to hold the value of the pointer even after it has been freed? Is that right or is there still an error? 2. Is the following piece of code right? I have an array of pointers and want to point one of the elements in the array to a given memory location allocated for another pointer. -
char * setParam(char * params[], unsigned char * map, int n, char * val) {
-
params[n] = val;
-
setBit(map, n, 1);
-
return params[n];
-
}
-
-
void removeParam(char * params[], unsigned char * map, int n) {
-
if(getBit(map, n)) {
-
printf("sletter: %s\n",params[n]);
-
free(params[n]);
-
setBit(map,n,0);
-
}
-
}
-
-
int main() {
-
unsigned char status = 0;
-
char * params[5];
-
-
char * val1 = malloc(30);
-
strcpy(val1, "Hei og hå!");
-
setParam(¶ms[0], &status, 0, val1)
-
removeParam(params, &status, 0);
-
}
NOTICE! The get- and setBitmap functions is a bitmap to keep track of used and unused pointers and is known to work.
It compiles and executes right, but here as well as the previos code, the value of the pointer is accesable after the memory is freed...
Freeing memory does not "reset" a pointer. It will still point at the address reserved by malloc. It's just that the memory itself is unused or, possibly, now used for something else.
Banfa 9,065
Recognized Expert Moderator Expert
It seems to me that you need to look up the standard library function strcpy.
boxfish 469
Recognized Expert Contributor
You don't have to cast malloc, and you probably don't want to, as it doesn't help but can hurt.
I thought you had to cast it because this code - char * val1 = malloc(30);
-
strcpy(val1, "Hei og hå!");
-
cout << val1;
-
free(val1);
didn't compile on my Dev-C++ compiler. It says
invalid conversion from `void*' to `char*'
The error went away when I did a typecast. Is there anything I'm doing wrong? I also found a couple of examples, like this one, which use a type cast.
JosAH 11,448
Recognized Expert MVP
I thought you had to cast it because this code
didn't compile on my Dev-C++ compiler. It says
invalid conversion from `void*' to `char*'
The error went away when I did a typecast. Is there anything I'm doing wrong? I also found a couple of examples, like this one, which use a type cast.
The OP is using C, you were using C++. In C you can freely implicitly cast to and
from a void* to any other type of pointer. In C++ the cast needs to be explicit.
kind regards,
Jos
boxfish 469
Recognized Expert Contributor
Okay, thanks, I get it. I had expected that all C code would compile for me, because of the backwards-compatibility thing.
Freeing memory does not "reset" a pointer. It will still point at the address reserved by malloc. It's just that the memory itself is unused or, possibly, now used for something else.
That sounds right. I've really tried and failed a lot the last few days, but it's starting to pay off :)
Thanks a lot for all the answers, explanations and your time.
Yours sincerely
Laharl 849
Recognized Expert Contributor
Okay, thanks, I get it. I had expected that all C code would compile for me, because of the backwards-compatibility thing.
Not all C is valid C++, just most of it.
Sign in to post your reply or Sign up for a free account.
Similar topics |
by: Bret |
last post by:
I'm curious why char** argv is acceptable in the main() declaration.
In the comp.lang.c FAQ (question 6.18) it says that pointers to
pointers and pointers to an array are not interchangable. ...
|
by: Sona |
last post by:
I understand the problem I'm having but am not sure how to fix it. My
code passes two char* to a function which reads in some strings from a
file and copies the contents into the two char*s. Now...
|
by: sieg1974 |
last post by:
Hi,
I have made this simple program to understand char ** pointers, but I
still having many questions.
int main()
{
char ** testPointerPointerChar = 0;
char * A = "string01";
|
by: gaga |
last post by:
I can't seem to get this to work:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *names;
char **np;
|
by: jab3 |
last post by:
(again :))
Hello everyone.
I'll ask this even at risk of being accused of not researching adequately.
My question (before longer reasoning) is: How does declaring (or defining,
whatever) a...
| |
by: max |
last post by:
Dear all,
I did the following analysis to conclude that the following pointer
types are not compatible. Please let me know If my analysis and
interpretation of the C standard are correct:
...
|
by: Xavier Roche |
last post by:
Hi folks,
I have a probably rather silly question: is casting a char array in a
char* a potential source of aliasing bug ?
Example: a fonction returning a buffer taken in a circular buffer
...
|
by: arnuld |
last post by:
i see the use of pointers, from K&R2 but what is the use of:
1. "pointer to pointer":
char c;
char** ppc;
2. pointer to function:
|
by: arnuld |
last post by:
int main()
{
const char* arr = {"bjarne", "stroustrup", "c++"};
char* parr = &arr;
}
this gives an error:
$ g++ test.cpp
test.cpp: In function 'int main()':
test.cpp:4: error: cannot...
|
by: Paul Brettschneider |
last post by:
Hello all,
consider the following code:
typedef char T;
class test {
T *data;
public:
void f(T, T, T);
void f2(T, T, T);
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...
| |