Consider this piece of C code:
int main(int argc, char *argv[])
{
char ***map = malloc(sizeof(char *) * 4);
char *a[] = { "hello", "world" };
char *b[] = { "foo", "bar" };
char *c[] = { "test", "last" };
map[0] = a;
map[1] = b;
map[2] = c;
char *p = NULL;
int offset = 30; // buffer exploited!
p = **map + offset;
if (!p)
puts("err"); // not detected?
else
printf("%p %s\n", p, p);
return 0;
}
How to get (eficiently and safely) upper bounding address of map, to avoid bufferoverflow errors, because if I access char **p = map[random_offset]; directly eventually will cause runtime error
By default there is no detection of out of bounds access. You have to handle it yourself.
Your assumption that out of bounds pointers have null value is wrong and the following the condition is incorrect.
if (!p)
puts("err"); // not detected?
Accessing random memory loations using pointer arithmatic is allowed in C but not valid.
You have to keep track of the address you are accessing yourself. This can be eased by using access through array indices rather than using pointer arithmetic. (e.g. map[entryID][0] for key or map[entryID][1] for value). This makes it easy to check if entryID exceeds the maximum index. 0-1 are by contract always valid.
Update:
If you want to keep track of the array statistics (such as maximum length, number of valid entries, ...) you have to take care of it yourself. You could achieve this by embedding your map pointer into a struct together with the needed statistic fields:
typedef struct MyMap {
char ***map;
unsigned int capacity;
unsigned int last_index;
}tMyMap;
//...
void useTheMap(tMyMap *map);
// ...
tMyMap mapInstance;
mapInstance.map = malloc(...);
mapInstance.capacity = ...;
mapInstance.last_index = ...;
useTheMap(&mapInstance);
// ...
for (int i = 0;i < mapInstance.last_index;i++) {
//...
}
Of course you have to take care of updating the statistic fields yourself. But this would give you the oportunity to find out the capacity of the map at runtime at cost of the overhead for updating the statistic fields... (It's actually the way how e.g. other - more convenient - string implementations in other languages work)
You have allocated space for a sentinel in the map, but not assigned it a value. Either, use something like memset(...) or map [3] = (char **) 0; to force the terminator.
Then, you can track the length of the map, or scan linearly from the beginning until reaching a match or the terminator before stopping. Junix response provides for the first alternative. If the list is not ordered, then a linear search is necessary in any event and the length will not really help.
The observation about the error in the type in malloc(...) is correct - the language, however, is not able to verify the type against the LHS value in C. Fortunately char * and char ** are both pointer types, and have the same size.
Related
Recently I was pondering over this question: how to make an easier way to iterate over an array of pointer in C.
If I create an array of string in C, it should look like this right?
int size = 5;
char ** strArr = (char **) malloc(sizeof(char *) * size);
if (strArr == NULL) return;
But the problem is, when you want to iterate over this array for some reason (like printing all values inside it), you have to keep track of its current size, storing in another variable.
That's not a problem, but if you create lots of arrays, you have to keep track of every single one of their sizes inside the code. If you pass this array to another function, you must pass its size as well.
void PrintValues (char ** arr, int size) {
for (int i = 0; i < size; i++)
printf("%s\n", arr[i]);
}
But when iterating over a string, it's different. You have the '\0' character, which specifies the end of the string. So, you could iterate over a string like this, with not need to keep its size value:
char * str = (char *) malloc(sizeof(char) * 4);
str[0] = 'a';
str[1] = 'b';
str[2] = 'c';
str[3] = '\0';
for (int i = 0; str[i] != '\0'; i++)
printf("%c", str[i]);
printf("\n");
Now my question:
Is it ok or morally right to allocate +1 unit in an array of pointers to maintain its tail as NULL?
char ** strArr = (char **) malloc(sizeof(char *) * (5 +1);
if (strArr == NULL) return;
strArr[0] = PseudoFunc_NewString("Car");
strArr[1] = PseudoFunc_NewString("Car#1");
strArr[2] = PseudoFunc_NewString("Car#2");
strArr[3] = PseudoFunc_NewString("Tree");
strArr[4] = PseudoFunc_NewString("Tree#1");
strArr[5] = NULL; // Stop iteration here as next element is not allocated
Then I could use the NULL pointer to control the iterator:
void PrintValues (char ** arr) {
for (int i = 0; arr[i] != NULL; i++)
printf("%s\n", arr[i]);
}
This would help me to keep the code cleaner, though it would consume more memory as a pointer size is larger than a integer size.
Also, when programming with event-based libraries, like Gtk, the size values would be released from the stack at some point, so I would have to create a pointer to dynamically store the size value for example.
In cases like this, it ok to do this? Or is it considered something bad?
Is this technique only used with char pointers because char type has a size of only 1 byte?
I miss having a foreach iterator in C...
Now my question: Is it ok or morally right to allocate +1 unit in an array of pointers to maintain its tail as NULL?
This is ok, the final NULL is called a sentinel value and using one is somewhat common practice. This is most often used when you don't even know the size of the data for some reason.
It is however, not the best solution, because you have to iterate over all the data to find the size. Solutions that store the size separately are much faster. An arrays of structs for example, containing both size and data in the same place.
Now my question: Is it ok or morally right to allocate +1 unit in an array of pointers to maintain its tail as NULL?
In C this is quite a common pattern, and it has a name. You're simply using a sentinel value.
As long as your list can not contain null pointers normally this is fine. It is a bit error-prone in general however, then again, that's C for you.
It's ok, and is a commonly used pattern.
As an alternative you can use a struct, in there you can create a size variable where you can store the current size of the array, and pass the struct as argument. The advantage is that you don't need to iterate through the entire array to know its size.
Example:
Live demo
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
char **strArr;
int size;
} MyStruct;
void PrintValues(MyStruct arr) //pass the struct as an argument
{
for (int i = 0; i < arr.size; i++) //use the size passed in the struct
printf("%s\n", arr.strArr[i]);
}
int main()
{
// using the variable to extract the size, to avoid silent errors
// also removed the cast for the same reason
char **strArr = malloc(sizeof *strArr * 5);
if (strArr == NULL) return EXIT_FAILURE;
strArr[0] = "Car";
strArr[1] = "Car#1";
strArr[2] = "Car#2";
strArr[3] = "Tree";
strArr[4] = "Tree#1";
MyStruct strt = { strArr, 5 }; // initialize the struct
PrintValues(strt); //voila
free(strArr); // don't forget to free the allacated memory
return EXIT_SUCCESS;
}
This allows for direct access to an index with error checking:
// here if the array index exists, it will be printed
// otherwise no, allows for O(1) access error free
if(arr.size > 6){
printf("%s\n", arr.strArr[6]);
}
This probably has been asked already, but I'm unable to find anything on it.
I have a string array, where the numbers of strings in it is determined at runtime (the max string length is known, if that helps). Since I need global access to that array, I used a pointer and malloc'ed enough space to it when I actually know how much has to fit in there:
char *global_strings;
void some_func(int strings_nr, int strings_size)
{
global_strings = (char*) malloc(strings_nr* strings_size* sizeof(char));
}
What would be the correct way in C to use this pointer like a two-dimensional char array equivalent to
global_strings[strings_nr][strings_size] ?
As a global pointer to 2D data, whose N*M characteristics defined at run-time, I'd recommend a helper function to access the strings rather than directly use it. Make it inline or as a macro if desired.
char *global_strings = NULL;
size_t global_strings_nr = 0;
size_t global_strings_size = 0;
// Allocation -
// OK to call again, but prior data may not be organized well with a new string_size
// More code needed to handle that.
void some_func(int strings_nr, int strings_size) {
global_strings_nr = strings_nr; // save for later use
global_strings_size = strings_size; // save for later use
global_strings = realloc(global_strings,
sizeof *global_strings * strings_nr * strings_size);
if (global_strings == NULL) {
global_strings_nr = global_strings_size = 0;
}
}
// Access function
char *global_strings_get(size_t index) {
if (index >= global_strings_nr) {
return NULL;
}
return global_strings + index*global_strings_size;
}
#define GLOBAL_STRINGS_GET_WO_CHECK(index) \
(global_strings + (index)*global_strings_size)
Better to use size_t for array indexing and sizing than int.
Casts not needed.
Memory calculations should begin with a size_t rather than int * int * size_t.
I need to write a function the takes:
an unknown type array, size of the array and size of the elements
and return an array of pointers: first the negative value and then the positive values. this is what Iv done so far:
void *mix(void *A, int nElementsA, int sizeOfAnElement) {
char** res = (char**)malloc(sizeof(char*)*nElementsA*sizeOfAnElement);
char* p = (char *)A;
char* bStart = res[0];
char* bEnd = res[nElementsA*sizeOfAnElement - sizeOfAnElement];
while (p<(char*)A + nElementsA*sizeOfAnElement) {
if (*(int*)p>0) {
bStart = p;
bStart += sizeOfAnElement;
}
else {
bEnd = p;
bEnd -= sizeOfAnElement;
}
p += sizeOfAnElement;
}
return res;
}
and i get array full of rubbish,
what Iv dove wrong?
First of all: What you are trying to do is impossible and makes little sense.
You say that you have: an unknown type array Therefore you can not access any elements of the array. Doing:
(*(int*)p
means that you assume the elements to be of type int (or compatible). This obviously conflict with the type being unknown.
Besides that....
This line
malloc(sizeof(char*)*nElementsA*sizeOfAnElement);
allocates too much memory. It shall only allocate a pointer for each element, i.e.
malloc(sizeof(char*)*nElementsA);
Fixed:
void *mix(void *A, int nElementsA, int sizeOfAnElement,
int (*isPositive)(const void *)) {
// Allocate a `char*` array containing `nElementsA` pointers.
char **res = malloc(nElementsA * sizeof *res);
// &p[i] == &A[i]
char (*p)[sizeOfAnElement] = A;
// bStart points to the first result element.
char **bStart = &res[0];
// bEnd points to the last result element.
char **bEnd = &res[nElementsA - 1];
// Loop through the array,
// adding &A[i] at the start of the result array if positive,
// else at the end of the result array.
for (int i = 0; i < nElementsA; i++) {
if (isPositive(p[i])) {
*bStart = p[i];
bStart++;
}
else {
*bEnd = p[i];
bEnd--;
}
}
return res;
}
Your understanding of what needed to be allocated and how to use your pointers was wrong.
If you want to create an array of pointers, then you need only allocate nElementsA pointers, not nElementsA * sizeOfAnElement pointers (you're storing pointers, not copies of the objects to which they point).
Then you created and used bStart and bEnd incorrectly. If you want to move through an array of int objects, then you need an int* object. In the case of bStart and bEnd, you want to move through an array of char*, so you need a char**.
I added a function pointer parameter, so you can work with types other than int (else what's the point of using void *A and sizeOfAnElement instead of int *A?) If you need help with that, there are plenty of answers here and tutorials for you to find via search engine.
I also took the liberty of changing p to a pointer to an array, so the compiler can perform the pointer arithmetic for you rather than you doing it yourself. You can change it back if you like. If you want to use pointers in the loop (i.e. you can't use i), here's a version of the loop that does that:
// I added the typedef for more easily understood declarations of `p` and `end`.
typedef char array_alias_t[sizeOfAnElement];
// p's type is the same as in the previous code (char (*)[sizeOfAnElement]).
array_alias_t *p = A;
// p + x == &p[x], and &p[nElementsA] is one element past the end of A,
// which is allowed by ISO C, provided you don't dereference the pointer
// (i.e. *end is not allowed).
for (array_alias_t *end = p + nElementsA; p != end; p++) {
if (isPositive(*p)) {
*bStart = *p;
bStart++;
} else {
*bEnd = *p;
bEnd--;
}
}
I want to filter an strings array passed in, something like this:
char **
filter_vids(char **vids, size_t n) {
int i;
int count = 0;
char ** filted = malloc(n * sizeof(char *));
for(i = 0; i < n; i++){
filted[i] = (char*)malloc(50 * sizeof(char));
}
for(i = 0; i < n; i++) {
if(some_filter(vids[i])) {
strcpy(filted[count++], vids[i]);
printf("in filter:%s\n", vids[i]);
}
}
return filted;
}
But the caller may not known the length of return array, it's extractly the counter variable, so what's the best practice of returning an array while telling him the right length of array?
such as
char **
filter_vids(char **vids, size_t n, int *output_length)
It's the best practice of using output_length?
I edit this function to this, as your suggestions:
char **
filter_vids(char **vids, size_t n) {
int i;
int count = 0;
char ** filted = malloc((n + 1) * sizeof(char *));
for(i = 0; i < n; i++) {
if(vids[i][0] <= 'f') {
filted[count++] = strdup(vids[i]);
}
}
filted[count] = NULL;
return filted;
}
To pass a pointer to an integer length variable whose value is then set in the function is certainly a good way. As Malcolm said, it is also general and can be used for sets of values which do not have an "invalid" member.
In the case of pointers with their invalid null pointer value one can mark the end of valid entries with a null pointer. For example, the array of string pointers which the C run time uses to pass command line arguments to main is thus terminated.
Which method to choose depends a little on how the caller wants to use the resulting array. If it is processed sequentially, a (while *p){ ..; ++p; } feels idiomatic. If, on the other hand, you need random access and must perform the equivalent of a strlen before you can do anything with the array, then it is probably better to return the length via a pointed-to length variable right away.
Two remarks:
First, note the difference between
a valid pointer to an empty string (if somebody called, let's say, myProg par1 "" par2, argv[2] could be a valid pointer to a zero byte);
and a null pointer which is pointing nowhere; in the example, argv[4] would be the null pointer, indicating the end of the argument list.
Second, You malloc more memory than you need which is wasteful in the case of longer strings and/or strict filters. You could instead allocate the string on demand inside the if clause.
These are common options:
Receive the allowed size as parameter by pointer, overwrite it with the actual size, return the array as return value.
Receive the output array as parameter by pointer, update as required, return the actual size as return value.
Append a sentinel value to the output array (here a null pointer), as suggested in the other answer.
Use a more sophisticated data structure as a return value. You could use a struct, which stores the size alongside the array or a linked list.
Example (untested):
typedef char* mystring;
typedef mystring* mystringarray;
typedef struct { mystringarray *arr; size_t size } mysizedstringarray;
/* returns filtered array, size will be updated to reflect the valid size */
mystringarray* myfun1(mystringarray in, size_t* size);
/* out will be allocated and populated, actual size is returned */
size_t myfun2(mystringarray in, size_t size, mystringarray* out);
/* output array contains valid items until sentinel value (NULL) is reached */
mystringarray* myfun3(mystringarray in, size_t size);
/* returns filtered array with actual size */
mysizedstringarray myfun4(mystringarray in, size_t size);
I needed a character array containing a dynamic number of character arrays based on the number of files in a specific folder. I was able to accomplish this by initializing char (*FullPathNames)[MAX_FILENAME_AND_PATHNAME_LENGTH] and then using FullPathNames = malloc( sizeof(*FullPathNames) * NumOfFiles * MAX_FILENAME_AND_PATHNAME_LENGTH ) ) after I know how many files another function discovered( which I have not provided). This process works flawlessly.
I can only use ANSI C; I am specifically using LabWindows CVI 8.1, to compile my code. I cannot use any other compiler. The below code is doing what I want. I can fill this array easily enough with the following code:
Strcpy(FullPathNames[0],”Test Word”);
char (*FullPathNames)[MAX_FILENAME_AND_PATHNAME_LENGTH];
size_t Size;
NumOfFiles = NumberOfUserFiles(“*.txt”, “C:\\ProgramData” );
FullPathNames = malloc( sizeof(*FullPathNames) * NumOfFiles * MAX_FILENAME_AND_PATHNAME_LENGTH ) );
Size = sizeof(*FullPathNames) * NumOfFiles;
Memset(FullPathNames,0,Size);
However, I would like to be able to pass FullPathNames which is an array of pointers to a variable amount of character arrays into a method. I want this method to be able to remove a single character array at a given index.
I am calling the method with the following code.
Remove_Element(FullPathNames,1, NumOfFiles);
The code for Remove_Element:
void Remove_Element( char (*Array)[MAX_FILENAME_AND_PATHNAME_LEN], int Index, int Array_Length )
{
int i;
char String[MAX_FILENAME_AND_PATHNAME_LEN];
char (*NewArray)[MAX_FILENAME_AND_PATHNAME_LEN];
int NewLength = Array_Length - 1;
size_t Size;
NewArray = malloc( sizeof( *NewArray) * NewLength * ( MAX_FILENAME_AND_PATHNAME_LEN ) );
Size = sizeof( *NewArray ) * NewLength;
memset(NewArray, 0, Size);
for ( i = Index; i < Array_Length - 1; i++ )
{
memcpy(String,Array[i+1],MAX_FILENAME_AND_PATHNAME_LEN); // Remove last index to avoid duplication
strcpy( Array[Index], String );
}
Array = NewArray;
}
My expectation of what I have currently is that the original data of FullPathNames remains except for the index that I removed, by copying data from index + 1, and the original pointers contained within FullPathNames is of course updated. Since I also wanted to shrink the array I attempted to set the array equal to the new array. The following information explains my attempts at debugging this behavior.
The watch variables present the following information as I enter the method.
FullPathNames = XXXXXX
NewArray = Unallocated
Array = XXXXXX
After I fill the new temporary Array the following happens:
FullPathNames = XXXXXX
NewArray = YYYYY
Array = XXXXXX
As I exit the method the following happens:
FullPathNames = XXXXXX
NewArray = YYYYY
Array = YYYYY
I was attempting to modify FullPathNames by passing it in as a pointer. I originally tried this task by using realloc but that just resulted in a free pointer exception.
Notes:
MAX_FILENAME_AND_PATHNAME_LENGTH = 516;
If I understand correctly, what you want to do is to modify the FullPathNames Pointer in the code part where you initialize your original array.
With your declartion of FullPatchNames
char (*FullPathNames)[MAX_FILENAME_AND_PATHNAME_LENGTH]
you basically declare a pointer to an array of MAX_FILENAME_AND_PATHNAME_LENGTH char elements. With your call to void Remove_Element(...) you just give a copy of this pointer to the local variable Array valid inside your function. Because of this Array = NewArray;, only changes the local copy of your pointer inside the function, not FullPathNames.
If you want to change the value of FullPathNames you must give a pointer to this pointer to your function. The Prototype of Remove_Element must look like this:
void Remove_Element( char (**Array)[MAX_FILENAME_AND_PATHNAME_LEN],
int Index, int Array_Length )
Now Array is a Pointer to an Pointer to an (one dimansional) array of char. By dereferencing this Pointer, you can change your original Pointer FullPathNames to point to your new object you created inside your function. You must modify the call to this function to Remove_Element(&FullPathNames,1, NumOfFiles);. To read from Array, you must dereference it using the * operator:
memcpy(String,*Array[i+1],MAX_FILENAME_AND_PATHNAME_LEN);
...
Array = NewArray;
Warning: This code will now produce a memory leak, since you are loosing your reference to your orignal object. You should remove this using the free() function somewhere in your code!
There seems to exist a certain lack of knowledge about the syntax in C language first and foremost.
char (*FullPathNames)[MAX_FILENAME_AND_PATHNAME_LENGTH]
This is one example. The syntax shown here would be read by a c- programmer as:
Semicolon is missing - maybe #define voodoo somewhere!
char (*FullPathNames)... - a function pointer! oh wait why square brackets next?!
Maybe he wanted to say char *FullPathNames; or he wanted char FullPathNames[MAX_FILENAME_AND_PATH_NAME_LENGTH]; Hm...
So here the first 101:
char foo[50]; // A fixed size array with capacity 50 (49 chars + '\0' max).
char *foo = NULL; // a uninitialized pointer to some char.
char (*foo)(); // a pointer to a function of signature: char(void).
char *foobar[50]; // This is an array of 50 pointers to char.
Depending on where your char foo[50]; is located (in the code file, in a function, in a structure definition), the storage used for it varies.
char foo1[50]; // zerovars section.
char foo2[50] = { 0 }; // initvars section
char foo3[50] = "Hello World!"; // also initvars section
void FooTheFoo( const char *foo )
{
if(NULL != foo )
{
printf("foo = %s\n", foo);
}
}
int main(int argc, const char *argv[])
{
char bar[50] = "Message from the past."; // bar is located on the stack (automatic variable).
FooTheFoo(bar); // fixed size array or dynamic array - passed as a (const pointer) in C.
return 0;
}
Now we got the basics down, lets look at 2-dimensional dynamic array.
char **matrix = NULL;
A pointer to a pointer of char. Or a pointer to an array of pointers to chars or an array of pointers to pointers to arrays of chars.
As lined out, there is no "meta" information regarding to what a char* or a char ** point to beyond that finally the dereferenced item will be of type char. And that it is a pointer to a pointer.
If you want to make a 2-dimensional array out of it, you have to initialize accordingly:
const size_t ROW_COUNT = 5;
const size_T COL_COUNT = 10;
char **myMatrix = malloc(sizeof(char *) * ROW_COUNT);
// check if malloc returned NULL of course!
if( NULL != myMatrix )
{
for(size_t row = 0; row < ROW_COUNT; row++ )
{
myMatrix[row] = malloc(sizeof(char) * COL_COUNT);
if( NULL == myMatrix[row] ) PanicAndCryOutLoudInDespair();
for(size_t col = 0; col < COL_COUNT; col++ )
{
myMatrix[row][col] = 0;
}
// of course you could also write instead of inner for - loop:
// memset(myMatrix[row], 0, sizeof(char) * COL_COUNT);
}
}
Last not least, how to pass such a 2-dimensional array to a function? As the char** construct does not contain the meta information regarding sizes, in the general (inner not a 0 terminated string) case, you would do it like that:
void FooIt( const char **matrix, size_t rowCount, size_t colCount )
{ // Note: standard checks omitted! (NULL != matrix, ...)
putchar(matrix[0][0]);
}
Last, if you want to get rid of your 2D dynamic array again, you need to properly free it.
void Cleanup2DArray( char **matrix, size_t rowCount )
{
for(size_t row = 0; row < rowCount; row++ )
{
free(matrix[row];
}
free(matrix);
}
The only thing more to say about it I leave to other gentle contributors. One thing coming to mind is how to express const-ness correctly for those multi-dimensional things.
const char **
const char const * const *
etc.
With this, you should be able to spot the places where you went wrong in your code and fix it.
The pointer you're passing is just a value. That it holds an address means you can dereference it to modify what it points to, but it doesn't mean changing its value directly (your assignment statement) will affect the caller-parameter. Like everything else in C, if you want to modify something by-address, then an address is exactly what you need to do it. If the thing you're modifying is a pointer, then the address of the pointer (through a pointer-to-pointer parameter) is the generally prescribed solution.
However, I can tell you the syntax and housekeeping to do that is... uninviting in your case. A simple pointer is easy enough, but a pointer-to-array-of-N isn't so simply. Were I you his would simply use the return result of the function itself, which is otherwise currently being unused and void. Declare your function like this:
char (*Remove_Element( char (*Array)[MAX_FILENAME_AND_PATHNAME_LEN],
int Index, int Array_Length ))[MAX_FILENAME_AND_PATHNAME_LEN]
{
....
return Array; // or whatever else you want to return so
// long as the type is correct.
}
and simply have the caller do this:
Array = RemoveElement(Array, Index, Array_Length);
A working variation of my solution appears below. The reason I had to do it this way is because while I was able to dereference (**Array)[MAX_FILENAME_AND_PATHNAME_LEN] I was only able to modify the first string array in the array.
The string array was initialized and filled several strings. While I could reference a string contained within *Array[0] but was unable to reference any of the other strings. The resulting array will replace the original array. This method will only work in the initial code block where the array to be replaced is initialized.
#define MAX_FILENAME_AND_PATHNAME_LEN MAX_FILENAME_LEN + MAX_PATHNAME_LEN
/*
This method was designed to free the memory allocated to an array.
*/
void FreeFileAndPathArrays( char (*Array)[MAX_FILENAME_AND_PATHNAME_LEN] )
{
free( Array );
}
/*
This method was designed to remove an index from an array. The result of this method will shrink the array by one.
*/
void Remove_Element( char (**ArrayPointer)[MAX_FILENAME_AND_PATHNAME_LEN],int Index, int *Array_Length, char (*Array)[MAX_FILENAME_AND_PATHNAME_LEN] )
{
int i = 0;
int j = 0;
char String[MAX_FILENAME_AND_PATHNAME_LEN];
char (*NewArray)[MAX_FILENAME_AND_PATHNAME_LEN];
char (*GC)[MAX_FILENAME_AND_PATHNAME_LEN];
int Length = *Array_Length;
int NewLength = Length - 1;
size_t Size;
NewArray = malloc( sizeof( *NewArray) * NewLength * ( MAX_FILENAME_AND_PATHNAME_LEN ) );
Size = sizeof( *NewArray ) * NewLength;
memset(NewArray, 0, Size);
UI_Display("Test Block:");
for ( j = 0; j < NewLength; j++ )
{
if ( j != Index )
{
memcpy(String,Array[j],MAX_FILENAME_AND_PATHNAME_LEN);
strcpy( Array[Index], String );
Fill(NewArray,String,j);
UI_Display(String);
}
}
GC = Array;
*ArrayPointer = NewArray;
free(GC);
*Array_Length = *Array_Length - 1;
}
/*
This method was designed to place a string into an index.
*/
void Fill( char (*Array)[MAX_FILENAME_AND_PATHNAME_LEN], const char * String, int Index)
{
strcpy( Array[Index], String );
}
/*
This method was designed to place fill each string array contained within the array of string arrays with 0's.
*/
void PrepareFileAndPathArrays( char (*FullPathNames)[MAX_FILENAME_AND_PATHNAME_LEN], int ROWS )
{
size_t Size;
Size = sizeof( *FullPathNames ) * ROWS;
memset(FullPathNames, 0, Size);
}