Specifying external memory for the Linker - c

When compiling my code, I get the Data Memory overflow-error, even though all extra variables added since last successful compile, are declared with pointers to external SRAM-memory.
I found examples of specifying the external memory with linker flags, these did however not help. (Example for my SRAM memory range: 0x1000 ->0x1FFF):
-Wl,--section-start,.data=0x801000,--defsym=__heap_end=0x801FFF
Checking the box for 'External ram check for memory overflow' in AVR/GNU Common / General-settings did not solve the issue.
Code for the external declarations which are causing the overflow:
Header-file:
typedef struct menu_page menu_page;
typedef struct game_setting game_setting;
struct game_setting
{
uint8_t* parameter;
uint8_t alternatives[6];
uint8_t alternatives_number;
};
struct menu_page
{
char title[20];
menu_page* submenu_pages[4];
menu_page* parent_menu_page;
uint8_t submenu_pages_number;
//Used to set values for settings:
game_setting* setting;
};
typedef enum {TEXBOX_LEFT, TEXTBOX_CENTER, TEXTBOX_RIGHT}TextBox_pos;
static volatile menu_page* menu_page_address_offset;
static volatile game_setting* game_setting_address_offset;
static uint8_t game_parameters_array[5];
//Indicates if the game should start/stop:
static volatile game_setting* game_status;
static volatile menu_page* start_game;
//***********************************
static volatile game_setting* solenoid_param;
static volatile menu_page* solenoid_control;
static volatile game_setting* servo_param;
static volatile menu_page* servo_control;
static volatile game_setting* motor_param;
static volatile menu_page* motor_control; //Controller layout
//***********************************
static volatile menu_page* controller_layout;
static volatile menu_page* settings_advanced;
static volatile game_setting* difficulty_param;
static volatile menu_page* settings_difficulty;
static volatile menu_page* menu_setting;
static volatile menu_page* main_menu;
init-function in source file:
void menu_init()
{
menu_page_address_offset = 0x1C01;
game_setting_address_offset = 0x1F01;
game_status = game_setting_address_offset;
game_setting_address_offset += 1;
uint8_t alternatives[6];
game_status->parameter = &game_parameters_array[RUN_STATUS];
game_status->alternatives[0] = OFF;
game_status->alternatives[1] = ON;
game_status->alternatives_number = 2;
start_game = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&start_game->title, "Start game");
start_game->submenu_pages[0] = NULL;
start_game->parent_menu_page = main_menu;
start_game->submenu_pages_number = 0;
start_game->setting = &game_status;
solenoid_param = game_setting_address_offset;
game_setting_address_offset += 1;
solenoid_param->parameter = &game_parameters_array[SOLENOID];
solenoid_param->alternatives[0] = X_POSITION;
solenoid_param->alternatives[1] = Y_POSITION;
solenoid_param->alternatives[2] = LEFT_SLIDER;
solenoid_param->alternatives[3] = RIGHT_SLIDER;
solenoid_param->alternatives_number = 4;
solenoid_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&solenoid_control->title,"Solenoid");
solenoid_control->submenu_pages[0] = NULL;
solenoid_control->parent_menu_page = NULL;
solenoid_control->submenu_pages_number = 0;
solenoid_control->setting = &solenoid_param;
servo_param = game_setting_address_offset;
game_setting_address_offset += 1;
servo_param->parameter = &game_parameters_array[SERVO];
servo_param->alternatives[0] = X_POSITION;
servo_param->alternatives[1] = Y_POSITION;
servo_param->alternatives[2] = LEFT_SLIDER;
servo_param->alternatives[3] = RIGHT_SLIDER;
servo_param->alternatives_number = 4;
servo_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&servo_control->title, "Servo");
servo_control->submenu_pages[0] = NULL;
servo_control->parent_menu_page = NULL;
servo_control->submenu_pages_number = 0;
servo_control->setting = &servo_param;
motor_param = game_setting_address_offset;
game_setting_address_offset += 1;
motor_param->parameter = &game_parameters_array[MOTOR];
motor_param->alternatives[0] = X_POSITION;
motor_param->alternatives[1] = Y_POSITION;
motor_param->alternatives[2] = LEFT_SLIDER;
motor_param->alternatives[3] = RIGHT_SLIDER;
motor_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&motor_control->title, "Motor");
motor_control->submenu_pages[0] = NULL;
motor_control->parent_menu_page = NULL;
motor_control->submenu_pages_number = 0;
motor_control->setting = &motor_param;
#ifdef OLED_MENU_INIT_DEBUG
printf("Menu Title: %s\n", motor_control->title);
#endif
controller_layout = menu_page_address_offset;
//printf("Controller_layout addr: , %d\n", (int)menu_page_address_offset);
menu_page_address_offset += 1;
strcpy(controller_layout->title, "Controller Layout");
controller_layout->submenu_pages[0] = motor_control;
printf("motor_control : %X\n", motor_control);
controller_layout->submenu_pages[1] = servo_control;
controller_layout->submenu_pages[2] = solenoid_control;
controller_layout->parent_menu_page = NULL;
controller_layout->submenu_pages_number = 3;
controller_layout->setting = NULL;
settings_advanced = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_advanced->title, "Advanced Settings");
settings_advanced->submenu_pages[0] = NULL;
settings_advanced->parent_menu_page = NULL;
settings_advanced->submenu_pages_number = 0;
settings_advanced->setting = NULL;
difficulty_param->parameter = &game_parameters_array[DIFFICULTY];
difficulty_param->alternatives[0] = DIFFICULTY_EASY;
difficulty_param->alternatives[1] = DIFFICULTY_NORMAL;
difficulty_param->alternatives[2] = DIFFICULTY_HARD;
difficulty_param->alternatives_number = 3;
settings_difficulty = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_difficulty->title, "Difficulty");
settings_difficulty->submenu_pages[0] = NULL;
settings_difficulty->parent_menu_page = NULL;
settings_difficulty->submenu_pages_number = 0;
settings_difficulty->setting = &difficulty_param;
menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(menu_setting->title, "Settings");
menu_setting->submenu_pages[0] = controller_layout;
menu_setting->submenu_pages[1] = settings_difficulty;
menu_setting->submenu_pages[2] = settings_advanced;
//printf("Child 1 before: %d, %d",menu_setting->submenu_pages[0], controller_layout);
menu_setting->parent_menu_page = NULL;
menu_setting->submenu_pages_number = 3;
menu_setting->setting = NULL;
menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
main_menu = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(main_menu->title, "Main Menu");
main_menu->submenu_pages[0] = start_game;
main_menu->submenu_pages[1] = menu_setting;
main_menu->parent_menu_page = NULL;
main_menu->submenu_pages_number = 2;
main_menu->setting = NULL;
menu_assign_parents(&main_menu);
}
Data memory usage incereases from 82% to 102% with these additional declarations. I assume it should take less space? What am I doing wrong?

In this case, the it was unneccessary to hold the pointers in data memory, so I changed them to be temporary in the init()-function. Instead of keeping the pointers I chose to create a menu_page** table to hold the pointers in SRAM-memory.
relevant info in new header:
typedef enum {
//Run status flag for the game (Turn on/off):
GAME_STATUS,
//Holds possible parameters for solenoid control selection:
SOLENOID_PARAMETERS,
//Holds possible parameters for servo control selection:
SERVO_PARAMETERS,
//Holds possible parameters for motor control selection:
MOTOR_PARAMETERS,
//Holds possible parameters for difficulty:
DIFFICULTY_PARAMETERS,
GAME_SETTING_ELEMENTS = 5 // <-Has to be adjusted to number of elements in this enum!
}game_setting_data_index;
typedef enum {
//Pressing this option starts the game:
START_GAME,
//Menu for configuring which button to control solenoid:
SOLENOID_CONTROL,
// -||- which adc to control servo:
SERVO_CONTROL,
// -||- control motor:
MOTOR_CONTROL,
// Parent page for controller-configuration:
CONTROLLER_LAYOUT,
//More settings for the game:
SETTINGS_ADVANCED,
//Set difficulty:
SETTINGS_DIFFIULTY,
//Parent page for all settings, has previous pages as children:
MENU_SETTING,
MAIN_MENU,
MENU_PAGE_ELEMENTS = 9 //<--Has to be adjusted to number of elements in this enum!
}menu_page_data_index;
New init-function:
void menu_init()
{
const volatile menu_page* MENU_PAGE_SRAM_BASE_OFFSET = 0x1C01;
const volatile menu_page* GAME_SETTING_SRAM_BASE_OFFSET = 0x1E01;
//The menu_pages will be stored right after the last menu_page_address in SRAM_memory:
menu_page* menu_page_address_offset = MENU_PAGE_SRAM_BASE_OFFSET;
game_setting* game_setting_address_offset = GAME_SETTING_SRAM_BASE_OFFSET;
game_setting* game_status = game_setting_address_offset;
game_setting_address_offset += 1;
game_status->parameter = &game_parameters_array[RUN_STATUS];
game_status->alternatives[0] = OFF;
game_status->alternatives[1] = ON;
game_status->alternatives_number = 2;
menu_page* start_game = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&start_game->title, "Start game");
start_game->submenu_pages[0] = NULL;
start_game->parent_menu_page = NULL;
start_game->submenu_pages_number = 0;
start_game->setting = &game_status;
game_setting* solenoid_param = game_setting_address_offset;
game_setting_address_offset += 1;
solenoid_param->parameter = &game_parameters_array[SOLENOID];
solenoid_param->alternatives[0] = X_POSITION;
solenoid_param->alternatives[1] = Y_POSITION;
solenoid_param->alternatives[2] = LEFT_SLIDER;
solenoid_param->alternatives[3] = RIGHT_SLIDER;
solenoid_param->alternatives_number = 4;
menu_page* solenoid_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&solenoid_control->title,"Solenoid");
solenoid_control->submenu_pages[0] = NULL;
solenoid_control->parent_menu_page = NULL;
solenoid_control->submenu_pages_number = 0;
solenoid_control->setting = &solenoid_param;
game_setting* servo_param = game_setting_address_offset;
game_setting_address_offset += 1;
servo_param->parameter = &game_parameters_array[SERVO];
servo_param->alternatives[0] = X_POSITION;
servo_param->alternatives[1] = Y_POSITION;
servo_param->alternatives[2] = LEFT_SLIDER;
servo_param->alternatives[3] = RIGHT_SLIDER;
servo_param->alternatives_number = 4;
menu_page* servo_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&servo_control->title, "Servo");
servo_control->submenu_pages[0] = NULL;
servo_control->parent_menu_page = NULL;
servo_control->submenu_pages_number = 0;
servo_control->setting = &servo_param;
game_setting* motor_param = game_setting_address_offset;
game_setting_address_offset += 1;
motor_param->parameter = &game_parameters_array[MOTOR];
motor_param->alternatives[0] = X_POSITION;
motor_param->alternatives[1] = Y_POSITION;
motor_param->alternatives[2] = LEFT_SLIDER;
motor_param->alternatives[3] = RIGHT_SLIDER;
menu_page* motor_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&motor_control->title, "Motor");
motor_control->submenu_pages[0] = NULL;
motor_control->parent_menu_page = NULL;
motor_control->submenu_pages_number = 0;
motor_control->setting = &motor_param;
#ifdef OLED_MENU_INIT_DEBUG
printf("Menu Title: %s\n", motor_control->title);
#endif
menu_page* controller_layout = menu_page_address_offset;
//printf("Controller_layout addr: , %d\n", (int)menu_page_address_offset);
menu_page_address_offset += 1;
strcpy(controller_layout->title, "Controller Layout");
controller_layout->submenu_pages[0] = motor_control;
printf("motor_control : %X\n", motor_control);
controller_layout->submenu_pages[1] = servo_control;
controller_layout->submenu_pages[2] = solenoid_control;
controller_layout->parent_menu_page = NULL;
controller_layout->submenu_pages_number = 3;
controller_layout->setting = NULL;
menu_page* settings_advanced = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_advanced->title, "Advanced Settings");
settings_advanced->submenu_pages[0] = NULL;
settings_advanced->parent_menu_page = NULL;
settings_advanced->submenu_pages_number = 0;
settings_advanced->setting = NULL;
game_setting* difficulty_param = game_setting_address_offset;
game_setting_address_offset += 1;
difficulty_param->parameter = &game_parameters_array[DIFFICULTY];
difficulty_param->alternatives[0] = DIFFICULTY_EASY;
difficulty_param->alternatives[1] = DIFFICULTY_NORMAL;
difficulty_param->alternatives[2] = DIFFICULTY_HARD;
difficulty_param->alternatives_number = 3;
menu_page* settings_difficulty = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_difficulty->title, "Difficulty");
settings_difficulty->submenu_pages[0] = NULL;
settings_difficulty->parent_menu_page = NULL;
settings_difficulty->submenu_pages_number = 0;
settings_difficulty->setting = &difficulty_param;
menu_page *menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(menu_setting->title, "Settings");
menu_setting->submenu_pages[0] = controller_layout;
menu_setting->submenu_pages[1] = settings_difficulty;
menu_setting->submenu_pages[2] = settings_advanced;
//printf("Child 1 before: %d, %d",menu_setting->submenu_pages[0], controller_layout);
menu_setting->parent_menu_page = NULL;
menu_setting->submenu_pages_number = 3;
menu_setting->setting = NULL;
menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
menu_page* main_menu = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(main_menu->title, "Main Menu");
main_menu->submenu_pages[0] = start_game;
main_menu->submenu_pages[1] = menu_setting;
main_menu->parent_menu_page = NULL;
main_menu->submenu_pages_number = 2;
main_menu->setting = NULL;
//menu_assign_parents(&main_menu);
printf("Offsets: menupage: %X, game_setting: %X\n", menu_page_address_offset, game_setting_address_offset);
printf("Bytes per page: %d, %d\n", sizeof(menu_page), ((int)menu_page_address_offset-0x1C01)/10);
//Create address table at end of menu_page entries:
menu_page_address_table = menu_page_address_offset;
//Create address table at end of game_setting entries:
game_setting_address_table = game_setting_address_offset;
/*Game settings and pages have been placed in the order
of the menu_page_data_index-enum, address-tables should
be updated accordingly: */
printf("Menu address table: \n");
for (int i; i < MENU_PAGE_ELEMENTS; i++)
{
menu_page_address_table[i] = MENU_PAGE_SRAM_BASE_OFFSET + i;
printf("%X ", menu_page_address_table[i]);
}
printf("\nGame setting address table: \n");
for (int i; i < GAME_SETTING_ELEMENTS; i++)
{
game_setting_address_table[i] = GAME_SETTING_SRAM_BASE_OFFSET + i;
printf("%X ", game_setting_address_table[i]);
}
printf("\n");
}
Initializing each struct member seems a bit unneccessary, I'm gonna try to create an init-function for each struct instead.

Related

Can't Pass Array into UBO

I'm trying to initialize a setup in Vulkan where within the Shader there is a uniform array of textures and an corresponding arrays for the textures Width and Heights:
layout(binding=0) uniform UniformBufferObject {
mat4 model; //4x4 array of floats for uniform rotation and positioning
uint texW[32]; //Widths of ith texture
uint texH[32]; //Heights of ith texture
} ubo;
For some reason the shader only reads the mat4 and the first index of the texW. Everything else is initialized to 0.
Here's the Uniform Buffer Setup Code, for reference
void createUniformBuffers() {
/**Uniform Buffer for View Transformation*/
VkDeviceSize bufferSize = sizeof(uniformBufferObject);
uniformBuffers = malloc(swapChainSize * sizeof(VkBuffer));
uniformBuffersMemory = malloc(swapChainSize * sizeof (VkDeviceMemory));
for(uint i = 0; i < swapChainSize; i++)
createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffers[i], &uniformBuffersMemory[i]);
}
void createDescriptorPool() {
VkDescriptorPoolSize poolSizes[4];
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSizes[0].descriptorCount = swapChainSize;
poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
poolSizes[1].descriptorCount = swapChainSize;
VkDescriptorPoolCreateInfo poolInfo;
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.pNext = 0;
poolInfo.flags = 0;
poolInfo.poolSizeCount = 2;
poolInfo.pPoolSizes = poolSizes;
poolInfo.maxSets = swapChainSize;
if(vkCreateDescriptorPool(lDevice, &poolInfo, 0, & descriptorPool)) {
fprintf(stderr, "Failed to create Descriptor Pool\n");
exit(1);
}
}
void createDescriptorSets() {
VkDescriptorSetLayout layouts[swapChainSize];
for(uint i = 0; i < swapChainSize; i++) layouts[i] = descriptorSetLayout;
VkDescriptorSetAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.pNext = 0;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorSetCount = swapChainSize;
allocInfo.pSetLayouts = layouts;
descriptorSets = malloc(sizeof(VkDescriptorSet) * swapChainSize);
if(vkAllocateDescriptorSets(lDevice, &allocInfo, descriptorSets) ) {
fprintf(stderr,"Failed to allocate descriptor sets\n");
exit(1);
}
for(uint i = 0; i < swapChainSize; i++) {
VkDescriptorBufferInfo bufferInfo;
bufferInfo.buffer = uniformBuffers[i];
bufferInfo.offset = 0;
bufferInfo.range = VK_WHOLE_SIZE; //sizeof(uniformBufferObject);
VkWriteDescriptorSet descriptorWrites[2];
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].pNext = 0;
descriptorWrites[0].dstSet = descriptorSets[i];
descriptorWrites[0].dstBinding = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrites[0].descriptorCount = 1;
descriptorWrites[0].pBufferInfo = &bufferInfo;
descriptorWrites[0].pImageInfo = 0;
descriptorWrites[0].pTexelBufferView = 0;
descriptorWrites[0].dstArrayElement = 0;
VkDescriptorImageInfo imageInfo;
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfo.imageView = textureImageView[0];
imageInfo.sampler= textureSampler;
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[1].pNext = 0;
descriptorWrites[1].dstBinding = 1;
descriptorWrites[1].dstSet = descriptorSets[i];
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[1].descriptorCount = 1;
descriptorWrites[1].pImageInfo = &imageInfo;
descriptorWrites[1].pBufferInfo = 0;
descriptorWrites[1].pTexelBufferView = 0;
descriptorWrites[1].dstArrayElement = 0;
vkUpdateDescriptorSets(lDevice, 2, descriptorWrites,0,0);
}
}
Here's the code where the uniformBuffer is updated,
void updateUniformBuffer(uint currentImage) {
//FTR, I know I probably shouldn't remap each update, optimizing this is on my todo-list
vkMapMemory(lDevice, uniformBuffersMemory[currentImage], 0, sizeof(uniformBufferObject), 0, (void*) &uData);
memcpy(uData, &uniformData, sizeof(uniformBufferObject));
memset(uData->model, 0, sizeof(uData->model));
//Rotating the View, GLSL acknowledges this data
uData->model[2][2] = uData->model[3][3] = 1;
uData->model[0][0] = cosf(angle);
uData->model[0][1] = -sinf(angle);
uData->model[1][1] = cosf(angle);
uData->model[1][0] = sinf(angle);
angle+= 0.05f;
uData->texW[0] = 1024; //<-------GLSL Vertex Shader will acknowledge this =)
uData->texH[0] = 1024; //<-------GLSL Vertex Shader will ignore this =(
uData->texH[0] = 1024; //<-------GLSL Vertex Shader will also ignore this >_<
vkUnmapMemory(lDevice,uniformBuffersMemory[currentImage]);}
Any pointers or advice would be greatly appreciated.

Static struct initialization

I'm having issues with initializing certain structs which are declared as static in my library header
Header file:
struct game_setting
{
uint8_t parameter;
uint8_t alternatives[6];
uint8_t alternatives_number;
};
static game_setting game_status;
init-function in .c-file:
void menu_init()
{
static uint8_t game_parameters_array[6];
static game_setting game_status = {&game_parameters_array[RUN_STATUS],{OFF,ON},2}
Which returns 'Initializer element is not computable at load time'
I'm looking for an efficient way of assigning values to the static struct, what is wrong?
Main script
#define F_CPU 4915200UL
#define OFFSET 0x2000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include "SPI.h"
#include "MCP2515.h"
#include "MCP2515_Commands.h"
#include "adc.h"
#include "multiboard.h"
#include "OLED.h"
#include "OLED_menu.h"
#include "CAN.h"
#include "USART.h"
#define SPI_DEBUG
#define CAN_MESSAGE_DEBUG
#define UPDATEMESSAGES 255
// Define baud rate
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int main(void){
FILE fileHandle = USART_Init();
init_xMem();
stdout = &fileHandle;
stdin = &fileHandle;
printf("start of init\n\r");
menu_init();
printf("menu_init completed\n");
OLED_init();
CAN_init();
ADCInit();
initController();
can_message msg;
msg.id = 1;
controller C;
int i = 1;
while (1) {
menu_page_print_data();
_delay_ms(1000);
}
}
Full OLED_menu .c-file (relevant functions works without OLED.h definitions):
#include "OLED.h"
#include "OLED_menu.h"
void menu_init()
{
menu_page_address_offset = 0x1C01;
game_setting_address_offset = 0x1F01;
game_status = game_setting_address_offset;
game_setting_address_offset += 1;
uint8_t alternatives[6];
game_status->parameter = &game_parameters_array[RUN_STATUS];
game_status->alternatives[0] = OFF;
game_status->alternatives[1] = ON;
game_status->alternatives_number = 2;
start_game = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&start_game->title, "Start game");
start_game->submenu_pages[0] = NULL;
start_game->parent_menu_page = main_menu;
start_game->submenu_pages_number = 0;
start_game->setting = &game_status;
solenoid_param = game_setting_address_offset;
game_setting_address_offset += 1;
solenoid_param->parameter = &game_parameters_array[SOLENOID];
solenoid_param->alternatives[0] = X_POSITION;
solenoid_param->alternatives[1] = Y_POSITION;
solenoid_param->alternatives[2] = LEFT_SLIDER;
solenoid_param->alternatives[3] = RIGHT_SLIDER;
solenoid_param->alternatives_number = 4;
solenoid_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&solenoid_control->title,"Solenoid");
solenoid_control->submenu_pages[0] = NULL;
solenoid_control->parent_menu_page = NULL;
solenoid_control->submenu_pages_number = 0;
solenoid_control->setting = &solenoid_param;
servo_param = game_setting_address_offset;
game_setting_address_offset += 1;
servo_param->parameter = &game_parameters_array[SERVO];
servo_param->alternatives[0] = X_POSITION;
servo_param->alternatives[1] = Y_POSITION;
servo_param->alternatives[2] = LEFT_SLIDER;
servo_param->alternatives[3] = RIGHT_SLIDER;
servo_param->alternatives_number = 4;
servo_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&servo_control->title, "Servo");
servo_control->submenu_pages[0] = NULL;
servo_control->parent_menu_page = NULL;
servo_control->submenu_pages_number = 0;
servo_control->setting = &servo_param;
motor_param = game_setting_address_offset;
game_setting_address_offset += 1;
motor_param->parameter = &game_parameters_array[MOTOR];
motor_param->alternatives[0] = X_POSITION;
motor_param->alternatives[1] = Y_POSITION;
motor_param->alternatives[2] = LEFT_SLIDER;
motor_param->alternatives[3] = RIGHT_SLIDER;
motor_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&motor_control->title, "Motor");
motor_control->submenu_pages[0] = NULL;
motor_control->parent_menu_page = NULL;
motor_control->submenu_pages_number = 0;
motor_control->setting = &motor_param;
controller_layout = menu_page_address_offset;
//printf("Controller_layout addr: , %d\n", (int)menu_page_address_offset);
menu_page_address_offset += 1;
/*
strcpy(controller_layout->title, "Controller Layout");
controller_layout->submenu_pages[0] = motor_control;
printf("motor_control : %X\n", motor_control);
controller_layout->submenu_pages[1] = servo_control;
controller_layout->submenu_pages[2] = solenoid_control;
controller_layout->parent_menu_page = NULL;
controller_layout->submenu_pages_number = 3;
controller_layout->setting = NULL;
settings_advanced = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_advanced->title, "Advanced Settings");
settings_advanced->submenu_pages[0] = NULL;
settings_advanced->parent_menu_page = NULL;
settings_advanced->submenu_pages_number = 0;
settings_advanced->setting = NULL;
difficulty_param->parameter = &game_parameters_array[DIFFICULTY];
difficulty_param->alternatives[0] = DIFFICULTY_EASY;
difficulty_param->alternatives[1] = DIFFICULTY_NORMAL;
difficulty_param->alternatives[2] = DIFFICULTY_HARD;
difficulty_param->alternatives_number = 3;
settings_difficulty = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_difficulty->title, "Difficulty");
settings_difficulty->submenu_pages[0] = NULL;
settings_difficulty->parent_menu_page = NULL;
settings_difficulty->submenu_pages_number = 0;
settings_difficulty->setting = &difficulty_param;
menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(menu_setting->title, "Settings");
menu_setting->submenu_pages[0] = controller_layout;
menu_setting->submenu_pages[1] = settings_difficulty;
menu_setting->submenu_pages[2] = settings_advanced;
//printf("Child 1 before: %d, %d",menu_setting->submenu_pages[0], controller_layout);
menu_setting->parent_menu_page = NULL;
menu_setting->submenu_pages_number = 3;
menu_setting->setting = NULL;
*/
menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
main_menu = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(main_menu->title, "Main Menu");
main_menu->submenu_pages[0] = start_game;
main_menu->submenu_pages[1] = menu_setting;
main_menu->parent_menu_page = NULL;
main_menu->submenu_pages_number = 2;
main_menu->setting = NULL;
menu_assign_parents(&main_menu);
}
void game_setting_init(game_setting* setting, uint8_t* parameter, uint8_t* alternatives, uint8_t elements)
{
setting->parameter = parameter;
for (int i; i < elements; i++)
{
setting->alternatives[i] = alternatives[i];
}
}
int menu_assign_parents(menu_page* parent)
{
if(parent->submenu_pages_number > 6)
{
return -1;
}
for (int i; i < parent->submenu_pages_number; i++)
{
parent->submenu_pages[i]->parent_menu_page = parent;
if(menu_assign_parents(parent->submenu_pages[i]) == -1)
{
return -1;
}
}
return 0;
}
int menu_page_print(menu_page* page)
{
OLED_SRAM_Position_reset();
OLED_TextBox_clear((boundary) {0,127,0,7});
OLED_Goto_position(0,40);
//printf("%d parent, ", page->submenu_pages_number);
OLED_String_print(page->title, FONT_LARGE);
for (int i = 0; i < page->submenu_pages_number; i++)
{
OLED_Goto_position(i+1,5);
OLED_String_print(page->submenu_pages[i]->title, FONT_NORMAL);
//printf("%s\n", page->submenu_pages[i].title);
}
return 0;
}
menu_page* menu_page_select(menu_page* page,controller* C)
{
menu_page_print(page);
if(page->submenu_pages_number <= 0)
{
return (menu_page*)-1;
}
int submenu_number = -1;
int submenu_result = -1;
controller_direction generalDirection_prev;
while(!C->rightButton)
{
updateController(C);
if(generalDirection_prev != C->J.generalDirection)
{
switch(C->J.generalDirection)
{
case (DOWN):
submenu_number = (submenu_number + 1)%page->submenu_pages_number;
break;
case (UP):
submenu_number--;
if(submenu_number < 0)
{
submenu_number = page->submenu_pages_number-1;
}
break;
}
menu_page_selection_mark(submenu_number+1, page);
generalDirection_prev = C->J.generalDirection;
}
}
return &(page->submenu_pages[submenu_number]);
}
int TextBox_init(OLED_TextBox** box, char* str, TextBox_pos position, uint8_t line)
{
uint8_t StringLength = strlen(str);
printf("%d\n\r", StringLength);
if (118 / StringLength >= FONT_LARGE)
{
(*box)->FontSize = FONT_LARGE;
}
else if (118 / StringLength >= FONT_NORMAL)
{
(*box)->FontSize = FONT_NORMAL;
}
else if (118 / StringLength >= FONT_SMALL)
{
(*box)->FontSize = FONT_SMALL;
}
printf("%d\n\r", (*box)->FontSize);
switch (position)
{
case TEXBOX_LEFT:
(*box)->Boundaries = (boundary){5,5+StringLength*(*box)->FontSize,line,line};
case TEXTBOX_CENTER:
printf("%d\n\r", (128-(*box)->FontSize*StringLength)/2);
(*box)->Boundaries = (boundary){(128-(*box)->FontSize*StringLength)/2, (128+StringLength*(*box)->FontSize+1)/2,line,line};
printf("%d, %d, %d, %d nr1\n\r", (*box)->Boundaries.Left, (*box)->Boundaries.Right, (*box)->Boundaries.Top, (*box)->Boundaries.Bottom);
//printf("%d\n\r", (*box)->FontSize);
case TEXTBOX_RIGHT:
(*box)->Boundaries =(boundary){128-5-StringLength*(*box)->FontSize, 128-5,line,line};
}
(*box)->string = str;
return 0;
}
int menu_page_selection_mark(uint8_t rowIndex, menu_page* menu)
{
if(rowIndex < 1)
{
return -1;
}
//printf("Current index: %s\n", menu->submenu_pages[rowIndex].title);
static int rowIndex_prev = -1;
if(rowIndex_prev > -1)
{
OLED_Clear_line(rowIndex_prev);
OLED_Goto_position(rowIndex_prev, 5);
printf("title: %s\n", menu->submenu_pages[rowIndex_prev-1]->title);
OLED_String_print(menu->submenu_pages[rowIndex_prev-1]->title, FONT_LARGE);
}
OLED_Clear_line(rowIndex);
OLED_Goto_position(rowIndex, 7);
OLED_String_print(menu->submenu_pages[rowIndex-1]->title, FONT_LARGE);
OLED_String_print(" <-", FONT_LARGE);
rowIndex_prev = rowIndex;
return rowIndex;
}
void menu_page_print_data()
{
menu_page* page = main_menu;
printf("Menu page %s: Children: ", page->title);
for (int i; i < page->submenu_pages_number; i++)
{
printf("%s ", page->submenu_pages[i]->title);
}
printf("Parent: %s", page->parent_menu_page->title);
}
int menu_print_parameters(game_setting* settings, controller* C)
{
static uint8_t current_position = 1;
controller_direction generalDirection_prev;
menu_print_parameter_line(settings, LEFT, current_position);
while(!C->leftButton)
{
if(C->J.generalDirection != generalDirection_prev)
{
if (C->J.generalDirection == LEFT)
{
current_position = menu_print_parameter_line(settings, LEFT, current_position);
}
else if(C->J.generalDirection == RIGHT)
{
current_position = menu_print_parameter_line(settings, RIGHT, current_position);
}
}
}
}
int menu_print_parameter_line(game_setting* setting, controller_direction direction, uint8_t position)
{
char* string;
uint8_t next_position;
if(setting->alternatives_number == 0)
{
return -1;
}
if(direction == LEFT)
{
next_position = position -1;
}
else if(direction == RIGHT)
{
next_position = position +1;
}
OLED_Clear_line(6);
OLED_Goto_position(6,127);
OLED_String_print("<-", FONT_LARGE);
sprintf(&string, setting->alternatives[next_position]);
OLED_String_print(string, FONT_LARGE);
OLED_String_print("->", FONT_LARGE);
return next_position;
}
int menu_assign_parameters(menu_page* page, controller* C)
{
}
int menu_run(menu_page* page, controller* C)
{
menu_page* next_submenu_page;
menu_page* current_page = page;
while(next_submenu_page != -1)
{
current_page = next_submenu_page;
next_submenu_page = menu_page_select(current_page, C);
}
}
OLED_menu.h-file:
#ifndef OLED_MENU_H
#define OLED_MENU_H
#include "symbols_enums.h"
#include "OLED.h"
#include "multiboard.h"
#include "CAN_message_IDs.h"
#include <assert.h>
#include <string.h>
#include <avr/delay.h>
typedef struct menu_page menu_page;
typedef struct game_setting game_setting;
struct game_setting
{
uint8_t* parameter;
uint8_t alternatives[6];
uint8_t alternatives_number;
};
struct menu_page
{
char title[12];
menu_page* submenu_pages[4];
menu_page* parent_menu_page;
uint8_t submenu_pages_number;
//Used to set values for settings:
game_setting* setting;
};
typedef enum {TEXBOX_LEFT, TEXTBOX_CENTER, TEXTBOX_RIGHT}TextBox_pos;
static volatile menu_page* menu_page_address_offset;
static volatile game_setting* game_setting_address_offset;
static uint8_t game_parameters_array[5];
//Indicates if the game should start/stop:
static volatile game_setting* game_status;
static volatile menu_page* start_game;
//***********************************
static volatile game_setting* solenoid_param;
static volatile menu_page* solenoid_control;
static volatile game_setting* servo_param;
static volatile menu_page* servo_control;
static volatile game_setting* motor_param;
static volatile menu_page* motor_control; //Controller layout
//***********************************
static volatile menu_page* controller_layout;
static volatile menu_page* settings_advanced;
static volatile game_setting* difficulty_param;
static volatile menu_page* settings_difficulty;
static volatile menu_page* menu_setting;
static volatile menu_page* main_menu;
int menu_page_init(char*, menu_page*, menu_page*);
int menu_page_print(menu_page* page);
menu_page* menu_page_select(menu_page* page,controller* C);
int menu_page_selection_mark(uint8_t, menu_page*);
void menu_page_print_data();
int menu_print_parameter_line(game_setting*, controller_direction , uint8_t);
//int TextBox_init(OLED_TextBox**, char*, TextBox_pos, uint8_t);
#endif // OLED_MENU_H
I changed it to manually initialize one struct member at a time, which seems to work. However, when executing the program crashes before the menu_init() finishes due to these initializations:
menu_setting->submenu_pages[0] = controller_layout;
menu_setting->submenu_pages[1] = settings_difficulty;
menu_setting->submenu_pages[2] = settings_advanced;
main_menu->submenu_pages[0] = start_game;
main_menu->submenu_pages[1] = menu_setting;
controller_layout->submenu_pages[1] = servo_control;
controller_layout->submenu_pages[2] = solenoid_control
The initialization is providing the address of a thing, not the thing itself.
struct game_setting {
uint8_t parameter; // this is a byte
...
};
then in main()
{
static uint8_t game_parameters_array[6];
static struct game_setting game_status = {
&game_parameters_array[RUN_STATUS], // this is an address, not a byte
...
}
Also, I didn't see the definition of RUN_STATUS - is there any chance it's not a constant value? If it's a macro for something that can change (like a status flag), then it's not something suitable for indexing at load time to initialize this.

How can I sort an array that dependes on the quantity of other?

For Example I have this array:
G->colour = [2,1,0,1,0,1,0,1,2];
G->vertex = [1,2,3,4,5,6,7,8,9];
G->order = [1,2,3,4,5,6,7,8,9]; //the same of vertex
vertex 1 has colour 2, vertex 2 has colour 1, etc...
I need this solution G->order = [1,9,3,5,7,2,4,6,8]. I want to sort order using the number of vertex with same colour in growing order, i.e.,
I have two vertex with colour 2 (vertexes: 1, 9)
I have three vertex with colour 0 (vertexes: 3,5,7)
I have four vertex with colour 1 (vertexes : 2,4,6,8)
I have a function (RMBC) that sorts vertexes by colour. For example:
G->colour = [2,1,0,1,0,1,0,1,2];
G->order = [1,2,3,4,5,6,7,8,9];
This returns the function order = [3,5,7,2,4,6,8,1,9].
Besides I put the graph struct, and the greedy function that colours our vertexes.
I have much more code but I think that with this is okey.
Thanks!
typedef struct Graph
{
u32** vecinos;
u32* vertexes; // Position of vertexes
u32* color; //Structure type declarations do not support initializers
u32* grados;
u32* order; //it has the order of vertex for greedy
u32* visitados;
u32 m; //number of edges
u32 n; // number of vertex
u32 max; // number of colors
u32* indEnVecinos;
} Graph;
//RMBC
u32* vert_color;
char RMBC(Graph* G)
{
vert_color = G->color;
qsort(G->order, G->n, sizeof(u32), compColoresNormal);
return 0;
}
int compColoresNormal(const void *v1, const void *v2) {
u32 color1 = vert_color[*(const u32 *)v1 - 1];
u32 color2 = vert_color[*(const u32 *)v2 - 1];
if (color1 < color2)
{
return -1;
}
else if (color1 > color2)
{
return 1;
}
else
{
return 0;
}
}
// end RMBC
//Greedy
u32 Greedy(Graph* G)
{
u32** aux = G->vecinos;
u32 max_color = 0;
u32 nVer = G->n;
u32* color_vecinos = (u32*)malloc(sizeof(u32) * nVer);
memset(color_vecinos,0,nVer*sizeof(u32));
u32 indice = binarySearch(G->vertexes,0,nVer-1,G->order[0]);
G->color[indice] = 0;
G->visitados[indice] = 1;
u32 indice2 = 0;
u32 reset = 0;
for (u32 i = 1; i < nVer; ++i)
{
memset(color_vecinos,0,(reset+1)*sizeof(u32));
indice = binarySearch(G->vertexes,0,nVer-1,G->order[i]);
G->visitados[indice] = 1;
u32 color = 0;
reset = 0;
for (u32 i = 0; i < G->grados[indice]; ++i)
{
indice2 = binarySearch(G->vertexes,0,nVer-1,aux[G->indEnVecinos[indice]+i][1]);
if(G->visitados[indice2])
{
color_vecinos[G->color[indice2]] = 1;
if(reset < G->color[indice2]) reset = G->color[indice2];
}
}
for (u32 i = 0; i < nVer; ++i)
{
if(!color_vecinos[i])
{
color = i;
break;
}
}
G->color[indice] = color;
if(color > max_color) max_color = color;
if(reset < color) reset = color;
if(reset == nVer) reset--;
}
free(color_vecinos);
printf("terminé Greedy\n");
return max_color + 1;
}
//end Greedy
Are your colors and vertexes small numbers?
Encode the pair into a single number, sort, and decode
//G->colour = [2,1,0,1,0,1,0,1,2];
//G->vertex = [1,2,3,4,5,6,7,8,9];
colour * 1000 + vertex // based on small values!!
// encode to
// [2001, 1002, 3, 1004, 5, 1006, 7, 1008, 2009]
// sort to
// [2001, 2009, 3, 5, 7, 1002, 1004, 1006, 1008]
// decode to
//G->colour = [2,2,0,0,0,1,1,1,1];
//G->vertex = [1,9,3,5,7,2,4,6,8];
You know what the orders already are, they're those pointed to by v1 and v2 - store them into a variable and then:
int compColoresNormal(const void *v1, const void *v2) {
u32 order1 = *(const u32 *)v1;
u32 order2 = *(const u32 *)v2;
u32 color1 = vert_color[order1 - 1];
u32 color2 = vert_color[order2 - 1];
if (color1 < color2) {
return -1;
}
else if (color1 > color2) {
return 1;
}
// same color, use the order
else {
// return 0;
// branchless comparison expression
return (order2 < order1) - (order1 < order2);
}
}

Can someone explain what is wrong in my memory pool?

I compiled in C with -O3 and as share library on Linux Fedora x64. I used some mallocs after one. It seems when I work with wmemcpy and other functions in this family the change in one memory makes change in other...
I may violate size of memory? Or the problem is in my implementation?
Thanks in advance!
char* ur_free_available(struct memory_pool* pool, uint64_t sz)
{
uint64_t size = sz + sizeof(struct _MyPage);
if(pool->free_pos > 0)
{
if(pool->free_blocks[pool->free_pos - 1].pNext - pool->free_blocks[0].pNext > size)
{
uint64_t i, j;
char *addr;
struct _MyPage mpg;
for(i = 1; i < pool->free_pos; ++i)
{
if(pool->free_blocks[i].pNext - pool->free_blocks[0].pNext > size)
{
mpg.pPrev = NULL;
mpg.pNext = pool->free_blocks[i-1].pNext;
break;
}
}
pool->free_blocks[0].pPrev = NULL;
for(j = i; j < pool->free_pos; ++j)
{
if(j > 0)
pool->free_blocks[j-i].pPrev = pool->free_blocks[j-1].pPrev;
pool->free_blocks[j-i].pNext = pool->free_blocks[j].pNext;
}
pool->free_pos -= i;
pool->free_pos++;
memcpy(addr,(char*)&mpg, sizeof(mpg));
return &addr[0] + sizeof(struct _MyPage);
}
}
return NULL;
}
char* ur_mem_alloc(struct memory_pool* pool, uint64_t sz)
{
char *addr;
struct _MyPage mpg;
uint64_t size = sz + sizeof(mpg);
uint64_t j = 0, c, op;
if(pool->init_pos_is != 7)
{
//bzero(pool, sizeof(pool));
pool->init_pos_is = 7;
pool->free_pos = 0;
pool->hp_position = 0;
pool->st_position = 0;
mpg.pPrev = NULL;
for(c = 0; c < HP_CNT; c++)
pool->_extramem[c] = NULL;
pool->free_blocks[0].pNext = NULL;
//pool->_bytes = malloc(ST_MYPAGE_NO*ST_MYPAGE_SIZE);
//pthread_mutex_lock(&llk1);
_mpool = pool;
//pthread_mutex_unlock(&llk1);
atexit(equit);
}
if((addr = ur_free_available(pool, size)) != NULL)
{
return &addr[0];
}
op = pool->hp_position;
if(size + (ST_MYPAGE_SIZE * pool->st_position) > ST_MYPAGE_NO * ST_MYPAGE_SIZE)
{
uint64_t i;
for(i = 0; i < HP_CNT; ++i)
{
if(size < (pow(8, i)-pool->hp_position)*HP_MYPAGE_SIZE)
{
j = i;
if(pool->_extramem[i] == NULL)
{
pool->hp_position = 0;
pthread_mutex_lock(&llk2);
pool->_extramem[i] = (char*)malloc((uint64_t)pow(8, i) * HP_MYPAGE_SIZE);
pthread_mutex_unlock(&llk2);
}
break;
}
}
addr = &pool->_extramem[j][pool->hp_position*HP_MYPAGE_SIZE];
mpg.pPrev = (struct _MyPage*)&pool->_extramem[j][op*HP_MYPAGE_SIZE];
//printf("j %u %u %u\n", j, (uint64_t)size, (uint64_t)(pow(8, i-1))*HP_MYPAGE_SIZE);
pool->hp_position += floor(size/HP_MYPAGE_SIZE) + 1;
mpg.pNext = (struct _MyPage*)&pool->_extramem[j][pool->hp_position*HP_MYPAGE_SIZE];
memcpy(addr,(char*)&mpg, sizeof(mpg));
return &addr[0] + sizeof(struct _MyPage);
//
}
else
{
if(pool->st_position != 0)
{
mpg.pPrev = (struct _MyPage*)&pool->_extramem[j][(pool->hp_position)];
}
mpg.pNext = NULL;
pool->st_position += floor(size/ST_MYPAGE_SIZE);
addr = &pool->_bytes[(uint64_t)(pool->st_position-floor(size/ST_MYPAGE_SIZE)) * ST_MYPAGE_SIZE];
memcpy(addr,(char*)&mpg, sizeof(mpg));
return &addr[0] + sizeof(struct _MyPage);
}
}
void ur_mem_free(struct memory_pool* pool, char *addr)
{
if(addr == NULL) return;
pool->free_blocks[pool->free_pos].pPrev = pool->free_blocks[pool->free_pos].pNext;
pool->free_blocks[pool->free_pos].pNext = (struct _MyPage*)(addr - sizeof(struct _MyPage));
pool->free_pos++;
}
Breafly looking into function ur_free_available, the variable addr is not initialized, but you memcpy to it corrupting a random memory region. Then you try to return something using the same non-initialized pointer.

code with double free or corruption

I've got a double free problem in my program. I know which pointer is double freed but I cant figure out when was it freed first.
here is the code of my function :
int spectrum_gen(char *shift_r, char *rec_poly, char *redun_poly,int spectrum_length)
{
char *seq = NULL,*l_shift = NULL,loop_shift[SIZE];
int current_weight,*spectrum = NULL,*spect_numb = NULL,length=1,spectrum_size=0;
int index,index2,temp,temp2,*temp3;
/* int *weights = NULL; */
int *encoded_w = NULL;
int min_length,min_weight = 1000;
int looping = 0;
int **spectrum_content = NULL;
int *seq_w;
int *weight_table = symbols_weight(Q);
int *weights = NULL;
spectrum= (int*) malloc(sizeof(int));
seq = (char*) malloc(sizeof(char));
l_shift = (char*) malloc(SIZE*sizeof(char*));
weights = (int*) malloc(sizeof(int));
encoded_w = (int*) malloc(sizeof(int));
spect_numb = (int*) malloc(sizeof(int));
spectrum_content = (int**) malloc(sizeof(int*));
spectrum_content[1] = (int*) malloc(sizeof(int));
seq_w = (int*) malloc(sizeof(int));
strcpy(seq,"1");
convert_to_real(seq,1);
while(length > 0)
{
/* show_word(seq,length);
show_word(shift_r,SIZE);
puts(""); */
if(length == 1)
{
set2zero(shift_r,SIZE);
current_weight = RTZ_weight(0,seq[0],shift_r,rec_poly,redun_poly,encoded_w,seq_w,weight_table);
*seq_w += seq_weight(seq,1,weight_table);
}
else
{
current_weight = RTZ_weight(weights[length-2],seq[length-1],shift_r,rec_poly,redun_poly,encoded_w,seq_w,weight_table);
*seq_w += seq_weight(seq,length,weight_table);
/* show_word(shift_r,SIZE);
show_word(loop_shift,SIZE); */
if(looping==1 && str_cmp(shift_r,loop_shift,SIZE))
{
puts("looping sequence!!");
free(spectrum);
spectrum = NULL;
free(encoded_w);
encoded_w = NULL;
free(spect_numb);
spect_numb = NULL;
free(spectrum_content);
spectrum_content = NULL;
free(weights);
weights = NULL;
return 1;
break;
}
if(*encoded_w==weights[length-2] && looping==0 && length>3)
{
str_cpy(loop_shift,shift_r,SIZE);
looping = 1;
}
if(*encoded_w != weights[length-2])
{
looping = 0;
}
}
weights = realloc(weights,length*sizeof(int));
weights[length-1] = *encoded_w;
l_shift = realloc(l_shift,length*sizeof(char));
l_shift[length-1] = shift_r[SIZE-1];
if((shift_r[0] != 0) && (*encoded_w < spectrum_length))
{
if((temp = index4(current_weight,spectrum,spectrum_size,1,0)) != (-1))
{
spect_numb[temp]++;
if((temp2 = index4(*seq_w,spectrum_content[temp],spectrum_content[temp][0],2,1)) != (-1))
{ spectrum_content[temp][temp2+1]++;
}
else
{
spectrum_content[temp][0] += 2;
spectrum_content[temp] = realloc(spectrum_content[temp],spectrum_content[temp][0]*sizeof(int));
spectrum_content[temp][spectrum_content[temp][0]-2] = *seq_w;
spectrum_content[temp][spectrum_content[temp][0]-1] = 1;
}
}
else
{
spectrum_size++;
spectrum = realloc(spectrum,spectrum_size*sizeof(int));
spect_numb = realloc(spect_numb,spectrum_size*sizeof(int));
/* spectrum content : creation of a new table to store the inputs with output of weight current_weight*/
spectrum_content = realloc(spectrum_content,spectrum_size*sizeof(int*));
spectrum_content[spectrum_size-1] = (int*) malloc(3*sizeof(int));
spectrum_content[spectrum_size-1][0] = 3;
spectrum_content[spectrum_size-1][1] = *seq_w;
spectrum_content[spectrum_size-1][2] = 1;
spectrum[spectrum_size-1] = current_weight;
spect_numb[spectrum_size-1] = 1;
}
}
if(seq_equal_zero(shift_r,SIZE) || (*encoded_w >= spectrum_length))
{
while((length>0) && (seq[length-1] == Q-1))
{
length--;
for(index=0;index<SIZE-1;index++)
shift_r[index] = shift_r[index+1];
shift_r[SIZE-1] = l_shift[length-1];
}
for(index=0;index<SIZE-1;index++)
shift_r[index] = shift_r[index+1];
shift_r[SIZE-1] = l_shift[length-2];
seq[length-1] += 1;
}
else
{
length++;
seq = realloc(seq,length*sizeof(char));
seq[length-1] = 0;
}
/* printf("%d\n%d\n",*encoded_w,current_weight);
getchar(); */
}
/* sort(spectrum,spect_numb,spectrum_content,spectrum_size);*/
puts("Debut du spectre de ce codeur :");
for(index=0;spectrum[index+1]<=spectrum_length;index++)
{
printf("( ");
for(index2=1;index2<spectrum_content[index][0]-2;index2+=2)
{
printf("%d*I^%d + ",spectrum_content[index][index2+1],spectrum_content[index][index2]);
}
printf("%d*I^%d",spectrum_content[index][spectrum_content[index][0]-1],spectrum_content[index][spectrum_content[index][0]-2]);
printf(" )*O^%d + ",spectrum[index]);
}
printf("( ");
for(index2=1;index2<spectrum_content[index][0]-2;index2+=2)
{
printf("%d*I^%d + ",spectrum_content[index][index2+1],spectrum_content[index][index2]);
}
printf("%d*I^%d",spectrum_content[index][spectrum_content[index][0]-1],spectrum_content[index][spectrum_content[index][0]-2]);
printf(")*O^%d",spectrum[index]);
puts("");
free(seq);
seq = NULL;
free(spectrum);
spectrum = NULL;
free(encoded_w);
encoded_w = NULL;
free(spect_numb);
spect_numb = NULL;
free(spectrum_content);
spectrum_content = NULL;
free(weights);
weights = NULL;
return 0;
}
that pointer is called seq.
It would be so cool if someone helps me with this :)
here are the two functions that handle that pointer
void convert_to_real(char *word,int end)
{
int index;
for(index=0;index<end;index++) word[index]-='0';
}
i dont think it may be a problem
the only other function that handles that pointer is :
int seq_weight(char *seq,int end,int *weight_table)
{
int index,weight = 0;
for(index=0;index<end;index++)
if(seq[index]>=0 && seq[index]<Q)
weight += weight_table[(int)seq[index]];
return weight;
}
and i dont think it would cause a problem neither. :(
It's great that you set the pointer value to null after you have free'd it. So make use of that fact, and check for null before you free it - that way you avoid the double delete. Then you don't have to hunt for the double deletion because you will be protected from it.

Resources