Domanda

A part of my VS2012 Windows Phone project is in C. I've been struggling during one day trying to initialize an array to put stuff inside it.

Whenever I try to initialize it as global (outside any function), then I get a message telling me that I can't initialize it with a value that isn't a const.

const char* myArray = (const char*)malloc(256);
// Bad code: this isn't initialized with a const

If I don't initialize it with a value, then I'll have a message telling me to give it a value. So I assign a NULL value to the array.

const char* myArray = NULL;

Then I need to set a size somewhere, so I set the size within my main, or first function:

int myFirstFunctionInTheCode()
{
    myArray = (char*)malloc(256);    
}

Then I get something like: ';' expected before type

So I'm searching on forum and read that C in Visual Studio is C89, thus, I need to declare then to assign on two separate line, which isn't true elsewhere in my code, so I'm completely mixed-up about -real- standards. But I still get the same error when doing it on two lines.

I then decide to use some other tools from the available VS libraries to find out that in C, I can't include sstream, streambuf, etc, otherwise my whole project fails with thousands of bugs. So I could use boost to get a real stream libraries, but it's not compatible with Windows Phone because of some thread usage.

How do I set values inside a global, fixed-size array, in C (in Visual Studio)?

What I want to achieve is similar to something in C# like it:

static byte[] gentleCSharpArray = new byte[256];

private void easyShotCSharpFunction()
{
    gentleCSharpArray[0] = 0x57;
    gentleCSharpArray[1] = 0x54;
    gentleCSharpArray[2] = 0x46;
}

I never spent so much time trying to assign a value to an array, so I guess I'm totally wrong with my global char* arrays?

È stato utile?

Soluzione 2

You either:

const char my_array[] = "abcdef";

or:

char *my_array;

int main(void)
{
    my_array = malloc(some_size);
    /* initialize elements of my_array */
}

Example 1 makes no sense because you are attempting to initialize a static variable at runtime. Example 2 makes no sense because you are attempting to modify a const object. Essentially, you did the opposite of what could work in either situation.


What I want to achieve is similar to something in C# like it:

static byte[] gentleCSharpArray = new byte[256];

private void easyShotCSharpFunction()
{
    gentleCSharpArray[0] = 0x57;
    gentleCSharpArray[1] = 0x54;
    gentleCSharpArray[2] = 0x46;
}

Ok, then you want;

unsigned char arr[256];

void c_version(void)
{
    arr[0] = 0x57;
    arr[1] = 0x54;
    arr[2] = 0x46;
}

Altri suggerimenti

PART ONE

const char* myArray = (const char*)malloc(256);

This doesn't work because global variables in C are divvied into two spaces: the data segment and the bss segment. For example:

#include <stdio.h>
#include <stdlib.h>

int* myArray; // uninitialized, represented by bss segment
const char* myArray2 = "abc"; // initialized, goes into data segment

int main ()
{
    myArray = malloc(3*sizeof(int));
    myArray[0] = 111;
    myArray[1] = 222;
    myArray[2] = 333;

    int i;
    for (i=0; i<3; i++)
        printf("%d, %c\n", myArray[i], myArray2[i]);
    return 0;
}

When this is compiled, the const char* myArray2 = "abc"; does not translate into machine instructions. Instead, an image of what "abc" looks like in memory is created and put into the data segment, along with every other initialized global variable. Later, the program loader picks up that entire data segment and sticks it in memory, before your program even starts to run.

Uninitialized variables, like myArray in the example, don't even have that much happen. Rather, it is represented in the BSS segment as the compiler says, "we're going to need n bytes of memory reserved for uninitialized variables." Later, the program loader takes note of this and reserves those n bytes, before your program even starts to run.

Thus, it doesn't make sense to try and malloc when you initialize global variables, because when the globals are created your program isn't running yet. The machine instructions for malloc may not even be in memory yet!



PART TWO

static byte[] gentleCSharpArray = new byte[256];

private void easyShotCSharpFunction()
{
    gentleCSharpArray[0] = 0x57;
    gentleCSharpArray[1] = 0x54;
    gentleCSharpArray[2] = 0x46;
}

Okay, let's translate this bit by bit from C# to C. Are you using const in C because constant and static are (almost) synonyms in standard English? Because they're very different in programming.

  • The keyword const in C and C# means that the variable cannot be an L-value.
  • The keyword static in object-oriented languages (like C#) means that a function or variable is unchanging with respect to the object instance of its class. C has no objects and thus no analog.
  • The keyword static is used in plain C to mean that a variable is unchanging with respect to its invocation, or a function is unchanging with respect to where it can be seen (similar to private in C#, you can read more here).

But what are you really wanting to do there? Just reserve a huge chunk of memory for the program, right? C has no byte data type, but char is one byte in size; you can use that instead. The unsigned keyword makes it clear to program inspectors that this will not be used for a string:

// Compiled and ran with gcc -O0 -g -Wall on Ubuntu
#include <stdio.h>
#include <stdlib.h>

int* myArray;
const char* myArray2 = "abc";
unsigned char gentleCArray[256]; // <-- here's the declaration you want

static void easyShotCFunction()
{
    gentleCArray[0] = 0x57;
    gentleCArray[1] = 0x54;
    gentleCArray[2] = 0x46;
}

int main ()
{
    myArray = malloc(3*sizeof(int));
    myArray[0] = 111;
    myArray[1] = 222;
    myArray[2] = 333;

    easyShotCFunction();

    int i;
    for (i=0; i<3; i++)
        printf("%d, %c, 0x%x\n", myArray[i], myArray2[i], gentleCArray[i]);

    return 0;
}

When the program starts, gentleCArray will already be a pointer to 256 bytes of memory, most likely all zeroes. This is a consequence of the BSS segment I mentioned in part 1. Useful for doing your own memory management without malloc.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top