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 4934 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.
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. However the
declaration:
int main(int argc, char** argv)
is common.
|
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 when my function
returns, the values stored in the char* are some garbage values (perhaps
because I didn't allocate any memory for them).. but even if...
|
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 variable **var make it an array of pointers?
I realize that 'char **var' is a pointer to a pointer of type char (I hope).
And I realize that with...
| |
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:
const char * : "pointer to const-qualified char".
char *: "pointer to char".
Are these pointed-to types compatibles?
|
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
typedef struct foo_t foo_t;
struct foo_t {
int index;
|
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 convert 'const char* (*)' to 'char*' in
|
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
| |
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language...
|
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it. ...
|
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
|
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...
| |