該程式的主要思想是讀取資料并從緩沖區中提取檔案和檔案夾名稱。有效載荷資料可能如下所示cached_folder\test1_file:該函式get_folder_file_name提取檔案夾和檔案名,因為我們不知道資料的長度,因此根據需要使用 realloc() 函式來擴展緩沖區是合理的,因為它運行在記憶體有限的設備(嵌入式)上。
這是代碼:
typedef struct command_packet
{
uint32_t trigger_mode;
uint32_t command_status;
uint8_t payload_data[];
}COMMAND_PACKET;
//This function is called in main whenever there is incoming packet from TCP which has payload, command status and mode.
int32_t Analyse_stream(COMMAND_PACKET *pcommand, int32_t payload_data_length)
{
char *file_name = (char *)malloc(sizeof(char));
char *folder_name = (char *)malloc(sizeof(char));
int file_name_len= 0;
int folder_len = 0;
uint16_t status;
if ((status = get_folder_file_name(pcommand->payload_data, payload_data_length, file_name,folder_name, &file_name_len, &folder_len )) != SUCCESS)
{
free(file_name);
free(folder_name);
return status;
}
printf("File Name = %s\n", file_name);
printf("Folder = %s\n", folder_name);
free(file_name);
file_name = NULL;
free(folder_name);
folder_name = NULL;
}
//This function is called in stored_byte_stream to extract the folder and file name.
int32_t get_folder_file_name(uint8_t *payload_data, int32_t payload_data_len, char *file_name, char *folder_name, int32_t *file_name_len, int32_t *folder_len )
{
int i = 0;
int k=0;
// Check until null character to get the file name
// For alignment with u16, single null char is added at the end of the file name for
// a file name with strlen as odd and two null chars for a file name with even strlen
do{
if(payload_data[i] == '/')
{
if(i > 0)
k = i 1;
}
i ;
}while((*(payload_data i) != '\0') && (i < payload_data_len));
if(k == 0)
{
return FOLDER_NAME_IS_EMPTY;
}
if (i == payload_data_len)
{
// Null char search completed till the end of the payload len, No filename found
return FILE_NAME_NOT_FOUND;
}
if (i == 1)
{
// File Name strlen = 0; implies that the file name was not provided
return FILE_NAME_IS_EMPTY;
}
*folder_len = k 1;
*file_name_len= i-k 1;
folder_name = realloc(folder_name, sizeof(char) *(*folder_len));
strncpy(folder_name, (char *)payload_data, *folder_len -1);
file_name = realloc(file_name, sizeof(char) *(*file_name_len));
strncpy(file_name, (char *)payload_data k, *file_name_len);
return SUCCESS;
}
So, the issue I am facing is whenever the size of file_name_len or folder_len exceeds by 13, it prints nothing. The function get_folder_file_name returns empty file name or folder name whichever exceeds by 13. But in this same function folder_name & file name also has correct data but when they return if any of them exceeds by 13 length, buffer is empty. The issue gets fixed if I allocate fixed memory in initialization like char *file_name = (char *)malloc(15); and char *folder_name = (char *)malloc(15); and then doing realloc() it gets fixed. What I am doing wrong?
uj5u.com熱心網友回復:
代碼中的問題不在于您如何在 中分配字串get_folder_file_name,而在于您在該函式中所做的更改在Analyse_stream. 該函式中的file_nameandfile_folder仍然是您首先分配的 1 位元組塊。
(也許您在沒有分配的情況下嘗試列印這些字串時遇到了分段違規,并且您覺得需要先分配虛擬字串。這沒有必要;所有正確的分配都在get_folder_file_name.)
函式分配或重新分配記憶體是很常見的,因此有幾種用法。
回傳分配的資料的一個非常常見的方法:
char *get_file_name(..., uint32_t *length)
{
char *result;
// determine string s of length l somehow
result = malloc(l 1);
if (result == NULL) return NULL;
*length = l;
strcpy(result, s);
return result;
}
并像這樣使用它:
uint32_t len;
char *fn = get_file_name(..., &len);
// use fn if not NULL
free(fn);
在你的情況下,你有兩個字串,所以這可能是不切實際的。您還可以傳入一個指向每個字串的指標,以便該函式可以通過它修改字串,就像您已經為長度所做的那樣:
int get_ffn(..., char **file, char **folder)
{
// determine strings s1 and s2 of lengths l1 and l2 somehow
*file = malloc(l1 1);
*folder = malloc(l2 1);
if (*file == NULL || *folder == NULL) {
free(*file);
free(*folder);
return MEMORY_ERROR;
}
strcpy(*file, s1);
strcpy(*folder, s2);
return OK;
}
然后呼叫它Analyse_stream:
char *file;
char *folder;
int error = get_ffn(..., &file, &folder);
如果error == OK,字串現在具有相關資料,您必須free在使用后。
這是很多要傳遞的指標。您可以通過創建結構使界面更簡單:
struct path {
char *folder;
char *file;
};
int get_path(struct path *path, ...)
{
// ...
path->file = malloc(l1 1);
path->folder = malloc(l2 1);
return OK;
}
并這樣稱呼它:
struct path path;
if (get_path(&path, ...) == OK) ...
但是free在完成后,您必須像上面的其他示例一樣在結構中使用字串。
If you know that the size of your payload is reasonably small and fits on the stack, you could do without dynamic allocation and create two strings that another function fills in:
char file[PAYLOAD_MAX];
char folder[PAYLOAD_MAX];
if (fill_in_ff(..., file, folder) == OK) ...
The function then just takes these char arrays, which will "decay" into a pointer, as arguments:
int fill_in_ff(..., char *file, char *folder)
{
// ... find out lengths ...
// ... no allocation ...
memcpy(file, s1, l1);
memcpy(file, s2, l2);
s1[l1] = '\0';
s2[l2] = '\0';
return OK;
}
uj5u.com熱心網友回復:
回傳的指標realloc不一定仍然指向與傳遞的地址相同的地址。
在Analyse_stream,一旦你打電話, file_nameandfolder_name可能不再指向相關地址realloc。它們不會更新,因為get_folder_file_name您只更新這些變數的本地副本,而不是呼叫方的那些。
您基本上有這個常見問題錯誤的更復雜版本:動態記憶體訪問僅在函式內部起作用
盡管整個程式看起來很慢而且很復雜——為什么你不能靜態分配一個固定的大小,比如 256 位元組,然后跳過所有緩慢的重新分配呼叫呢?
與您的問題無關,請注意這strncpy是一個危險的功能,幾乎不應該用于任何目的。請參閱strcpy 危險嗎?應該改用什么?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/448220.html
