i created a code which will basically create an allocation of an array according to a size of a string,and store a pointer to the allocated array inside a for loop:
int Note;
int ifd;
char **pointer[ir];
for (Note = 0; Note < ir; ++Note) {
char ** Temp=malloc(Count(' ',Sentences[Note])*sizeof(char *));
ifd=StoreArr(Sentences[Note],Temp," ");
pointer[Note]=&Temp;
printer(*(pointer[Note]),ifd);
}
char **temp should create a new array each time the function starts,and pointer should store a pointer to the created array.when i print the created arrays,`(printer(pointer[Note]),ifd)). the output is correct:
hello
ola
hiya
howdy
eitan
eitanon
eitanya
but after exiting the for,and trying to print the first array of strings,i only receive
eitan
eitanon
eitanya
hence,i can persume that the Temp allocation does not create new memory,but simply overrides the existing allocation.
my question is how to solve the problem, in order to allocate new memory to Temp each time and by so allocate room for all arays in Sentences"
Thanks
It is quite hard to figure out what you meant, unless you post the whole code. However I suspect the following line of code to cause your issue:
char **pointer[ir]; //three pointers here
When you show the array with the following line. You are accessing the "local memory" and it works fine. However once you quit the function, the "local" variables are not longer accessible, thus using them will cause undefined behaviors.
printer(*(pointer[Note]),ifd);
I would recommend you to change your pointer to something like this:
char*** pointer;
Bottom line, never return an array declared with []
NB: Give your variables, methods, modules a descriptive name
Cheers !
Related
I need a function that receives an array of pointers to strings and it's size.
Then it should seek for those strings which occur in the array more than once - then I have to delete them and realloc the array.
Function should return new size of the array.
I'm trying to solve this, and not sure what`s wrong.
I want to move each string, that I want to delete, to the end of the array and then delete it, but not sure when the "realloc" should happen.
#include<stdio.h>
#include<stdlib.h>
int DeleteString(char** tab, int n){
char* check=malloc(sizeof(char)*100);
int deleted;
int i,j,g,h;
for(i=0;i<n;i++){
strcpy(check, tab[i]);
for(j=0;j<n;j++){
if(strcmp(check, tab[j]) == 0){
deleted++;
char* temp = malloc(sizeof(char)*100);
for(h=j;h<n-1;h++){
strcpy(temp, tab[h+1]);
strcpy(tab[h+1], check);
strcpy(tab[h], temp);
}
}
if(deleted>0){
realloc(tab, sizeof(char*)*(n-deleted));
}
}
}
return n-deleted;
}
For now there is "Segmentation fault" error
Oops, your code contains numerous problems, because you failed to observe some major rules of C language:
every non static variable shall be initialized (what about deleted?)
any object that was malloced shall be freed (what about check and temp.)
never change something that was passed as an input parameter to a function, or do not expect the change to be visible on return (tab has to be considered here because of next line).
allways assign the result of realloc because it can be different from the input pointer (realloc(tab, sizeof(char*)*(n-deleted));).
The first one is probably the cause of the segmentation fault because as deleted is unitialized its value is just undeterminated. But all problems should be fixed.
The reason for the SEGMENTATION FAULT is tab[0] store the address of the variable which stores the actual string.
Here tab[i] is in for loop,hence when it tries to fetch tab[1] itself memory error.
for(i=0;i<n;i++){
strcpy(check, tab[i]);...}
FOR EXAMPLE:
char *foo = "something";
char **ptr2;
ptr2 = &foo;
printf("check = %s", *ptr2);
for(int i=0;i<9;i++){
printf(" check = %c", ptr2[i]);
}
Output
check = something check = 4check = �check = pcheck =
Actally it is an error.
First of all, don't forget to initialise variables like deleted, as it has been said in other answers.
Next, you are supposed to free memory (as you are deleting items) and you only call malloc(3)). That seems a little counter-common sense, doesn't it?
Third, you make a lot of string copying in the loops, while it should be more efficient just to move pointers up, so you don't need to realloc the string elements and copy the cell contents (by the way, are you sure those strings will be feed to the function as malloc()d strings? I will assume that as you do)
Fourth, consider sorting the array first, so all the similar strings will be adjacent in the array. This has a cost O(n*log(n)) that, appended to the delete next string if equal (with cost O(n)) makes total cost O(n*(log(n)+1)) or O(n*log(n)) and not O(n^2) which is your actual cost)
Once sorted, only the strings deleted should be free(3)d, the pointers moved back to the start of the array as holes get appearing, and finally(when all is finished) you can just realloc(3) the array of pointers (only once, not at every pass through the loop)
Remaking the example is out of the scope of this answer, as it looks actually some school exercise. Sorry for that. I'm sure that the other hints will help you to retry the exercise with more success.
And think: thinking before writing is how one succeeds in this job.
I have a function that will add a new position to an array by reallocating new memory every time it is called.
The problem is that, for each call I need it to add one position to the array, starting from 1 at first call, but I understand that I have to mallocate before reallocating.
So my question is, can I initially do something like p = malloc(0) and then reallocate for example using p = (int *)realloc(p,sizeof(int)) inside my function? p is declared as int *p.
Maybe with a different syntax?
Of course I could make a condition in my function that would mallocate if memory hasn't been allocated before and reallocate if it has, but I am looking for a better way.
And the second problem I have is... Once reallocated more positions, I want to know the size of the array.
I know that if, for example, I declare an array a[10], the number of elements would be defined by sizeof(a)/sizeof(a[0]), but for some reason that doesn't work with arrays declared as pointers and then reallocated.
Any advice?
You could initialize your pointer to NULL, so that the first time you call realloc(yourPointer, yourSize), it will return the same value as malloc(yourSize).
For your second problem, you could use a struct that contains your pointer and a count member.
struct MyIntVector {
int * ptr;
size_t count;
}
Then you probably will want to define wrapper functions for malloc, realloc, and free (where you could reset ptr to NULL), that takes your struct as one of the parameters, and updates the struct as needed.
If you want to optimize this for pushing 1 element at a time, you could add a allocatedCount member, and only realloc if count == allocatedCount, with a new allocatedCount equals (for example) twice the old allocatedCount.
You should implement this in a MyIntVector_Push(MyIntVector *, int ) function.
You will then have a simplified c version of c++ std::vector<int> (but without automatic deallocation when the object goes out of scope).
As ThreeStarProgrammer57 said just use realloc.
realloc(NULL, nr_of_bytes) is equivalent to malloc(nr_of_bytes)
so
p = realloc(p, your_new_size)
will work just fine the first time if p is initialized to NULL. But be sure to pass the number of bytes you need after resizing, not the additional space that you want, as you have written your question.
As regarding the size, you have to keep track of it. That's the way C was designed.
I'm trying to make a program that basically picks a specific piece of source code and adds some other specific code into it. The program is just to big to put it all inside my question, but basically I have this "actors" struct:
typedef struct actors_s {
int num;
char *src_path;
char *project_path;
int *papify;
char *actor_path[];
} actors_s;
As you can see these are almost all pointers and the last one is an array of strings. This needs to be done this way because the number of "actor elements" depends on the input every time.
The problem:In an specific test case, I have a case with 'num' members in the actor_path array. Then I first call malloc only once this way:
*actors->actor_path = malloc(actors->num);
My logic tells me I shouldn't be using the '*' operator here but without it I get an error, this is possibly where the problem is. So, a function is called that allocates a new memory space for every new member (never going further of 'num' members):
int size = strlen(name)+strlen(actors->project_path)+strlen("/src/")+strlen(".c")+4;
actors->actor_path[i] = malloc(size);
(The malloc calls are properly tested if successful in the actual program)
This is called inside a function that is called for every "actor_path" element. In this test example I have three actors.
Mysteriously enough, on the third call of this malloc, the src_path element of the struct, which was properly allocated and set to a string once in the beginning of the program (and never touched again) is freed (I think so, at least it is changed into random numbers and symbols if I watch it in debug mode).
Anyone has any idea how and why is this possible? How do I fix this?
Thanks in advance.
EDIT:
Here are some screenshots from the debug watch window: http://imgur.com/a/aB1uv
First call to malloc: all OK.
Second call to malloc: all OK.
Third call to malloc: src_path gets erased!!
[] in latest array element is called flexible array member. It means structure have an array that starts just after structure itself, and its size is unspecified. You have to allocate memory for this manually. E.g.
actors_s *actor = malloc(sizeof(*actor) + sizeof(char*) * num);
Then just assign at most num elements into actor_path (each element is pointer to char).
about *actors->actor_path = malloc(actors->num);
actors->actor_path is an array of pointers, so *actors->actor_path is the first pointer in actors->actor_path, i.e. actors->actor_path[0].
When doing this, you actually allocate actors->num bytes memory for actors->actor_path[0].
Now, accessing actors->actor_path[0] is OK, while accessing actors->actor_path[1], actors->actor_path[2], actors->actor_path[3],... may cause problems, say, rewrite src_path...
about the solution
#keltar is right. In this way, the resource for actors->actor_path[0], actors->actor_path[1], actors->actor_path[2], ..., actors->actor_path[num - 1] is correctly allocated.
I am doing unit testing using google C++ testing tools. I am a novice C programmer as well as tester.
The following is my code snippet :
TEST_F (def_fix, SR_M_T) {
I_M_S * arg;
RM__S_F_R_T* message_data;
char mT[MAX_M_T_LENGTH] = "data";
strcpy(message_data->mT,mT);
message_data->rUID[0] = '\0';
message_data->uT[0] = '\0';
unsigned char buffer[sizeof(RM__S_F_R_T)+2];
memcpy(&buffer[2],message_data,sizeof(RM__S_F_R_T));
buffer[0] = 1; //This assignment is not important for this test
buffer[1] = 2; //This assignment is not important for this test
arg->payload_data = buffer;
handleSR(arg);
}
What the above does is creating an incoming message. This incoming message arg is to be used as parameter to call a function handleSR (void *).
def_fix is a default fixture class which contains SetUp() and TearDown() and nothing fancy in them.
RM__S_F_R_T is a structure which contains and 3 strings.
I_M_S is a structure containing a pointer to RM__S_F_R_T.
When I google test this, it gives a segmentation error. However when I change:
RM__S_FR_R_ * message_data; to RM__S_FR_R_ message_data;and use . operator instead of -> operator, things tend to work. Can anyone explain?
These two statements:
RM__S_F_R_T* message_data;
strcpy(message_data->mT,mT);
are the culprit. You never initialise the RM__S_F_R_T (who designed this thing?!) pointer. When not using it as a pointer, you create an instance on the stack that you can use.
To fix either don't use a pointer (you already found that out), or allocate memory:
message_data = malloc(sizeof(RM__S_F_R_T));
don't forget to free(message_data) when you are done with the instance, or you'll leak memory.
It's because you declare message_data to be a pointer, but don't point it at anything. So then it will point to a random memory location, causing undefined behavior when you dereference it.
Either declare it as not a pointer, or allocate memory for it.
You have not provided memory to RM__S_F_R_T*.Use message_data after
message_data = (RM__S_F_R_T*)malloc(sizeof(RM__S_F_R_T));
message_data doesn't point to anything. You need to pass an initialised RM__S_F_R_T struct pointer to your function as an argument or initialise it inside the function itself.
Further, I presume message_data->mT is a char pointer. It's not pointing to anything currently.
You can assign space for it using malloc, or if it's a char array then make sure it's big enough to hold mT into it (provided its struct is already initialised).
The above applies to all of message_data's members.
As the other posters have already mentioned, don't forget to free() anything you have malloc()-ed.
Initialize I_M_S * arg and RM__S_F_R_T* message_data:
I_M_S * arg = malloc(sizeof(I_M_S));
RM__S_F_R_T* message_data = malloc(sizeof(RM__S_F_R_T));
Also, make sure you don't use these allocated pointers after the scope of function TEST_F() because you assign arg->payload_data = buffer where scope of localized variable buffer ends after the function TEST_F().
And so, free these pointers before you leave TEST_F():
free(arg);
free(message_data);
I practiced an array of strings with no initial values.
Attempt 1
#include <stdio.h>
char *array[] = {};
int main(int argc, char *argv[]) {
array[0]="Hello";
array[1]="World";
char **i = array;
while (*i) {
printf("%d %s\n", i, *i);
i++;
}
}
$ gcc array_of_strings.c && ./a.out
6293704 Hello
6293712 World
It works fine.
Attempt 2
I thought I could move array pointer inside main function.
#include <stdio.h>
int main(int argc, char *argv[]) {
char *array[] = {};
array[0]="Hello";
array[1]="World";
char **i = array;
while (*i) {
printf("%d %s\n", i, *i);
i++;
}
}
$ gcc array_of_strings.c && ./a.out
-1899140568 (j͎?
-1899140560 World
-1899140552 ???%Y
-1899140544 1?I??^H??H???PTI???#
-1899140536 d?͎?
Segmentation fault
Huh, why it is not working? It causes "Segmentation fault" with ugly output.
Could somebody explain why I should not do this way?
You allocate an array with zero elements and then add two pointers to it. This writes outside of the array and causes a buffer overflow.
Incidentally, this overwrites unused memory if the array is allocated globally, but it overwrites the stack when it is allocated within main().
Two problems.
You aren't allocating space for the array items. With your empty initializer list you are allocating an empty array. When you write to array[0] and array[1] you are writing to memory you do not own.
You are getting lucky when you allocate the array globally. Global (aka statically-allocated) memory blocks tend to be filled with zeros. This is good for you because your while loop depends on their being a NULL pointer at the end of the array.
When you allocate on the stack and access memory past the end of the array you will get whatever happens to already be on the stack, which can be any arbitrary garbage. Your while (*i) loop doesn't get the NULL pointer it expects so it will keep on reading the garbage data until it finds some zeros that look like a NULL pointer.
To fix #1, give an explicit length to the array. To fix #2, you must explicitly add a NULL pointer to the end of the array.
char *array[3];
array[0]="Hello";
array[1]="World";
array[2]=NULL;
Also, for what it's worth, pointers aren't guaranteed to be the same size as ints. It is better to use %p to print pointers rather than %d.
printf("%p %s\n", i, *i);
In each of these cases, you are allocating an empty array, and then trying to insert items into it. C doesn't do any sort of resizing of arrays; if you insert items into an array beyond its length, it will just start overwriting any other data that might happen to come after the array. In your first case, when the array is a global, you manage to get lucky and apparently aren't breaking anything by writing past the end of the array, and furthermore are lucky that there is a null value just past the two that you insert, so your loop terminates at an appropriate place. In your second case, you happen to be overwriting your stack, which is used for storing local variables, passing arguments, return values, and return locations between functions. Thus, writing, and later reading, past the end of your array, is causing you to write all over your stack, and read random meaningless values.
Doing it on the second attempt declare the array on the stack and you then override arguments passed and at some point the return address at the end of the function.
The fact that it works in the first attempt is purely coincidental. You're still overriding memory you shouldn't but it currently does no harm.
You should not do it in both ways. In the first case, you were just lucky that you didn't overwrite some process-critical memory, in the second case you smashed the stack. Both cases might crash randomly because you are writing to memory that you did not reserve.
char *array[] = {};
This does reserve memory for zero entries, but with [0] = ... you're writing an element to a position for which you didn't allocate memory. You should read up about how to 1) define static arrays or 2) dynamically allocate arrays.