C Speicherplatz unterschied (struct Variable vs. normale)

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallo,

kurze Frage,

Wieso verbraucht eine "struct Variable" gleicher Typ, bisschen mehr Speicherplatz als eine normale Variable innerhalb einer Funktion?


struct variable


CodeBox C
int8_t ADE7758_readTEMP(void)
{
   ADE7758.Raw_Data[0] = 0;
   
   ADE7758.Raw_Data[0]    = (int8_t)ADE7758_read_int8(REG_TEMP); // raw data
   ADE7758.Raw_Data[0] -= (int8_t)40; // offset for this sensor
   ADE7758.Raw_Data[0] *= (int8_t)3; // 3°C/Bit
  //ADE7758.Raw_Data[0] += 21; // ambient temperature
   
   return ADE7758.Raw_Data[0];
}


"normale" variable


CodeBox C
int8_t ADE7758_readTEMP(void)
{
   int8_t temperature = 0;
   
   temperature    = ADE7758_read_int8(REG_TEMP); // raw data
   temperature -= 40; // offset for this sensor
   temperature *= 3; // 3°C/Bit
   //temperature += 21; // ambient temperature
   
   return temperature;
}


vorallem diese variable vom typ struct benutze ich schon für andere Sachen mit, dass müsste doch eigentlich nen Byte weniger sein wenn die "normale" Variable weg fällt oder?
 
Du müsstest mal die Definition des struct Blocks verraten. Der Datentyp ist zwar gleich, du hast aber anscheinend in der struct ein Array definiert?!
 
Das habe ich in der Headerdatei.



CodeBox C
/* extern variable(s) */
typedef struct
{
   uint8_t Raw_Data[3];
}ADE;

extern ADE ADE7758;


Ja habe ich. Mit 3 Speicherstellen.
Nur wieso wird das aufeinmal mehr wenn ich einen dieser Speicherplätze in anspruch nehme und sogar eine andere Variable raus haue?
 
Meine Vermutung ist, dass wenn du kein Element aus der struct nutzt, der Compiler den Speicherplatz für die struct nicht anlegt oder zuweist.
Nutzt du ein Element, zum Beispiel Raw_Data[0], dann wird der Speicherplatz für die Struct angelegt. Das sind mehr Byte als für die lokale int8_t Variable in deiner Funktion.

Noch ein Hinweis. Du arbeitest hier in der struct mit uint8_t und möchtest damit int8_t ersetzen, ich denke das möchtest du nicht.

Dirk :ciao:
 
Doch ich möchte an dieser Stelle mit "int8_t" arbeiten, dass passt.

Das mit dem Speicherplatz könnte ich nachvollziehen aber dieser wird schon in anderen Routinen benutzt. Also ich habe schon alle 3 Plätze in benutzung diese werden dann quasie nur überschrieben von der neuen Routine.
Verstehst du was ich meine @Dirk?

Hier z.B



CodeBox C
uint32_t ADE7758_read_uint24(uint8_t reg)
{
   ADE7758.Raw_Data[0] = 0;
   ADE7758.Raw_Data[1] = 0;
   ADE7758.Raw_Data[2] = 0;
   
   spi_enable_chip();
   spi_disable_chip(); // start transmission condition
   
   spi_master_transmit(reg); // register address
   
   spi_master_transmit(0x00); // dummy byte
   ADE7758.Raw_Data[0] = (uint8_t) spi_receive();
   
   spi_master_transmit(0x00); // dummy byte
   ADE7758.Raw_Data[1] = (uint8_t) spi_receive();
   
   spi_master_transmit(0x00); // dummy byte
   ADE7758.Raw_Data[2] = (uint8_t) spi_receive();
   
   spi_enable_chip(); // stop transmission condition
   
   int32_t result = ((uint32_t) ADE7758.Raw_Data[0]<< 16 | (uint32_t) ADE7758.Raw_Data[1]<< 8 | (uint32_t)ADE7758.Raw_Data[2]);
   
   
   return result;
}
 
Ja ich verstehe das schon.

Probiere es mal mit dem Attribut "packed".



CodeBox C
typedef __attribute__ ((packed)) struct {
   uint8_t Raw_Data[3];
} ADE;
 
Ja ich verstehe das schon.

Probiere es mal mit dem Attribut "packed".



CodeBox C
typedef __attribute__ ((packed)) struct {
   uint8_t Raw_Data[3];
} ADE;

Severity Code Description Project File Line
Warning 'packed' attribute ignored [-Wattributes]



CodeBox C
/* extern variable(s) */
typedef __attribute__ ((packed))struct
{
   uint8_t Raw_Data[3];
}ADE;

extern ADE ADE7758;
 
Gehts so?


CodeBox C
typedef struct
{
   uint8_t Raw_Data[3];
}  __attribute__((packed)) ADE;


Ich glaube es bringt hier aber nichts wegen dem Speicherplatz, das kannst du aber mal ausprobieren.
Hmmm, mir ist das Problem wahrscheinlich nich nicht so klar, wenn ich mehr Zeit habe, mache ich mir da nochmal Gedanken drüber :)

Dirk :ciao:
 
Ach warte mal, nun weiß ich was du meinst bzw. woran es liegt.

Die Variable int8_t wird in der Funktion definiert, sie ist somit nicht global. Die Struct Variable ist allerdings global definiert.

Entfernst du nun die "private" (lokale) int8_t in der Funktion ändert sich nichts an "Data Memory Usage". Die Variablen innerhalb einer Funktion oder Routine werden separat verwaltet.

Änderst du etwas an der globalen Variable (zB. hier das Array vergrößern), hat es direkt Einfluss auf die Belegung des SRAM.

EDIT:

Aus Atmel AVR4027: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers
Global variables and local values
In most cases, the use of global variables is not recommended. Use local variables whenever possible. If a variable is used only in a function, then it should be declared
inside he function as a local variable.

In theory, the choice of whether to declare a variable as a global or local variable should be decided by how it is used.

If a global variable is declared, a unique address in the SRAM will be assigned to this variable at program link time. Also accessing to a global variable will typically need extra bytes (usually two bytes for a 16 bits long address) to get its address.

Local variables are preferably assigned to a register or allocated to stack if supported when they are declared. As the function becomes active, the function’s local variables become active as well. Once the function exits, the function’s local variables can be removed.

In Table 3-3 there are two examples showing the effect of global variables and local variables.

In the left example, we have declared a byte-sized global variable. The output from the avr-size utility shows that we use 104 bytes of code space and one byte of data space with optimization level -Os (optimize for size).
In the right example, after we declared the variable inside main() function as local variable, the code space is reduced to 84 bytes and no SRAM is used.
global-local-vars.png
 
Zuletzt bearbeitet:
Ah okay, also ist es sinnvoller die Variable wirklich in der Funktion zu deklarieren wenn man sie nicht unbedingt global braucht?
 
In diesem Beispiel ist die Definition einer Struktur eh sinnfrei, da sie nur einen Member beinhaltet. Man hat also keinen Nutzen dadurch; erst wenn mehrere Member dazu kommen wie:


CodeBox BascomAVR
Structure Auto
    Dim Hersteller As String
    Dim ModellName As String
    Dim ModellNummer As Int32
End Structure

Dann übergibst du die Struktur an eine Funktion, statt alle Werte von Hand zu übergeben. Technisch gesehen ist also


CodeBox BascomAVR
Sub AutoHinzufuegen(NeuesAuto As Auto)

das Selbe wie


CodeBox BascomAVR
Sub AutoHinzufuegen(Hersteller As String, ModellName As String, ModellNummer As Int32)

Wobei das jetzt möglicherweise (technisch gesehen) vielleicht nicht ganz stimmt. In VB.Net ist es so wie beschrieben, es werden alle Werte kopiert (ByVal), Klassen werden per Verweis (Pointer, ByRef) übergeben. Wie das in C, vor allem AVR C aussieht weiß ich nicht.
Für VB.Net zählt: Strukturen haben manchmal Vorteile, aber manchmal eben auch Nachteile. Es kommt darauf an was drin gespeichert wird. Stell dir eine Bitmap in der Struktur vor, die müsste jedes Mal im Speicher kopiert werden, als Klasse verweist du immer auf die selbe Bitmap.
 
Lieber Tommy,

Das war nur ein Test, ich wollte mal wissen wieso er dort mehr Speicherplatz verbraucht als eine normale Variable.
 
War ja auch nur der Vollständigkeit halber.
Außerdem gibt es Googler die das vielleicht auch lesen ;)
 
Mal wieder sehr gut mitgedacht ;)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)