如何正确释放内存?
How to free memory properly?
请帮忙,我不知道如何正确释放内存。下面有代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INT_MSG_LEN 25;
enum {NO_ERROR = 0,
ERROR_INPUT = 100,
ERROR_LEN = 101};
static const char *error_texts[] = { "Error input!",
"Error lenghts!"};
void shift(char *msgEnc, char *msg, char *msgRes, char *mainMsg, char *alphabet, int offset);
void report_error(int error);
void print_error(int error);
int get_sameletters(char *msg, char *msgRes, int offset);
int get_letter(char letter, char *alphabet);
int compare(char *msgEnc, char *msg, char *msgRes, char *alphabet, int offset);
char *read_Input_Msg(int *msglen);
char rotate(char *original, int offset);
int main(int argc, char *argv[])
{
int ret = NO_ERROR;
char *msgEnc, *msg, alphabet[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int msgEncLen, msgLen;
msgEnc = msg = NULL;
msgEncLen = msgLen = 0;
msgEnc = read_Input_Msg(&msgEncLen);
if (msgEnc)
msg = read_Input_Msg(&msgLen);
if (msgEnc == NULL || msg == NULL)
ret = ERROR_INPUT;
else if (msgEncLen != msgLen)
ret = ERROR_LEN;
char msgRes[msgEncLen], mainMsg[msgEncLen];
if (ret == NO_ERROR)
shift(msgEnc, msg, msgRes, mainMsg, alphabet, msgEncLen);
else
print_error(ret);
free(msgEnc);
free(msg);
return ret;
}
void shift(char *msgEnc, char *msg, char *msgRes, char *mainMsg, char *alphabet, int offset)
{//function for decoding text by a defined offset
int dis;
dis = compare(msgEnc, msg, msgRes, alphabet, offset);
for (int i = 0; i<offset; ++i)
mainMsg[i] = msgEnc[i]+dis;
rotate(mainMsg, offset);
for(int i = 0; i<offset; ++i)
printf("%c", mainMsg[i]);
printf("\n");
}
void report_error(int error)
{//prints error
if (error >= ERROR_INPUT && error <= ERROR_LEN)
fprintf(stderr, "%s\n", error_texts[error - ERROR_INPUT]);
}
void print_error(int error)
{//what error it is
switch (error){
case ERROR_INPUT:
report_error(ERROR_INPUT);
break;
case ERROR_LEN:
report_error(ERROR_LEN);
break;
}
}
int get_sameletters(char *msg, char *msgRes, int offset)
{//gets count of sameletters between two strings
int sameLetters = 0;
for (int i = 0; i<offset-1; ++i){
if (msg[i] == msgRes[i])
sameLetters++;
}
return sameLetters;
}
int get_letter(char letter, char *alphabet)
{
int k = 0;
for (int i=0; alphabet[i]; ++i){
if (letter == alphabet[i])
k = i;
}
return k;
}
int compare(char *msgEnc, char *msg, char *msgRes, char *alphabet, int offset)
{//calculate a distance between first input string and string what will get after decryption
int distance, max_letters = 0;
for (int i = 0; alphabet[i]; ++i){
for (int j = 0; msgEnc[j]; ++j){
msgRes[j] = alphabet[(get_letter(msgEnc[j], alphabet) + i) % 52];
}
int sameLetters = get_sameletters(msg, msgRes, offset);
if (sameLetters >= max_letters){
max_letters = sameLetters;
distance = i;
}
}
return distance;
}
char *read_Input_Msg(int *msglen)
{//input messages, at the same time counts the length of the entered string
int capacity = INT_MSG_LEN;
char *msg = malloc(capacity);
int c, len = 0;
while ((c = getchar()) != EOF && c != '\n'){
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
free(msg);
msg = NULL;
len = 0;
break;
}
if (len == capacity){
char *tmp = realloc(msg, capacity * 2);
if (tmp == NULL){
free(msg);
msg = NULL;
len = 0;
break;
}
capacity *= 2;
msg = tmp;
}
msg[len++] = c;
}
*msglen = len;
return msg;
}
char rotate(char *original, int offset)
{
for (int i = 0; i<offset; ++i){
if (original[i] > 'Z' && original[i]<'a')
original[i] += 6;
else if (original[i] > 'z'){
int k = (int)original[i];
k -= 58;
original[i] = (char)k;
}
}
return *original;
}
When I run it through Valgrind, it says to me that I have errors with the allocated memory, says I do not free it. Writes that memory is not freed at 107.56 and 44 lines, more precisely
==56665== Conditional jump or move depends on uninitialised value(s)
==56665== at 0x4015BF: compare (main.c:107)
==56665== by 0x401468: shift (main.c:56)
==56665== by 0x4012C3: main (main.c:44)
==56665==
�elloword
==56665==
==56665== HEAP SUMMARY:
==56665== in use at exit: 0 bytes in 0 blocks
==56665== total heap usage: 4 allocs, 4 frees, 2,098 bytes allocated
==56665==
==56665== All heap blocks were freed -- no leaks are possible
==56665==
==56665== Use --track-origins=yes to see where uninitialised values come from
==56665== For lists of detected and suppressed errors, rerun with: -s
==56665== ERROR SUMMARY: 52 errors from 1 contexts (suppressed: 0 from 0)
好像释放了内存,但这还不够,因为一些函数调用后还有未释放的内存。我想我只是不知道如何释放它。在每个请求额外内存的函数结束时,我尝试通过 free(函数调用的数组)释放它,但在这种情况下它显示分段错误。如果您至少让我知道一些事情,我将不胜感激。
这里是输入示例
xUbbemehbT
XYlloworld
valgrind 输出不是说你有内存泄漏或者你没有正确释放一些东西。
如果您查看这部分输出:
==56665== HEAP SUMMARY:
==56665== in use at exit: 0 bytes in 0 blocks
==56665== total heap usage: 4 allocs, 4 frees, 2,098 bytes allocated
==56665==
==56665== All heap blocks were freed -- no leaks are possible
它表明所有分配的内存块都已释放。所以你没有分配问题。
重要的是这部分:
==56665== Conditional jump or move depends on uninitialised value(s)
==56665== at 0x4015BF: compare (main.c:107)
==56665== by 0x401468: shift (main.c:56)
==56665== by 0x4012C3: main (main.c:44)
这表示在第 107 行的 compare
函数(从第 56 行的 shift
调用,又从第 44 行的 main
调用),一个读取了从未初始化的值。这一行是:
for (int j = 0; msgEnc[j]; ++j){
所以这告诉我们您正在读取从未写入的 msgEnc
数组中的一个字节。该数组是在 read_Input_Msg
函数中写入的,该函数一次将一个字符读入数组。
因为这个数组应该是一个字符串,并且因为您一次读取一个字节,所以您需要手动添加一个您没有做的终止空字节。因此,当最终调用 compare
时,上面的行正在寻找一个从未明确写入的空字节,因此您最终会读取未初始化的字节。
在read_Input_Msg
中的主while
循环之后,在字符串末尾添加空字节:
while ((c = getchar()) != EOF && c != '\n'){
...
}
msg[len]=0;
请帮忙,我不知道如何正确释放内存。下面有代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INT_MSG_LEN 25;
enum {NO_ERROR = 0,
ERROR_INPUT = 100,
ERROR_LEN = 101};
static const char *error_texts[] = { "Error input!",
"Error lenghts!"};
void shift(char *msgEnc, char *msg, char *msgRes, char *mainMsg, char *alphabet, int offset);
void report_error(int error);
void print_error(int error);
int get_sameletters(char *msg, char *msgRes, int offset);
int get_letter(char letter, char *alphabet);
int compare(char *msgEnc, char *msg, char *msgRes, char *alphabet, int offset);
char *read_Input_Msg(int *msglen);
char rotate(char *original, int offset);
int main(int argc, char *argv[])
{
int ret = NO_ERROR;
char *msgEnc, *msg, alphabet[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int msgEncLen, msgLen;
msgEnc = msg = NULL;
msgEncLen = msgLen = 0;
msgEnc = read_Input_Msg(&msgEncLen);
if (msgEnc)
msg = read_Input_Msg(&msgLen);
if (msgEnc == NULL || msg == NULL)
ret = ERROR_INPUT;
else if (msgEncLen != msgLen)
ret = ERROR_LEN;
char msgRes[msgEncLen], mainMsg[msgEncLen];
if (ret == NO_ERROR)
shift(msgEnc, msg, msgRes, mainMsg, alphabet, msgEncLen);
else
print_error(ret);
free(msgEnc);
free(msg);
return ret;
}
void shift(char *msgEnc, char *msg, char *msgRes, char *mainMsg, char *alphabet, int offset)
{//function for decoding text by a defined offset
int dis;
dis = compare(msgEnc, msg, msgRes, alphabet, offset);
for (int i = 0; i<offset; ++i)
mainMsg[i] = msgEnc[i]+dis;
rotate(mainMsg, offset);
for(int i = 0; i<offset; ++i)
printf("%c", mainMsg[i]);
printf("\n");
}
void report_error(int error)
{//prints error
if (error >= ERROR_INPUT && error <= ERROR_LEN)
fprintf(stderr, "%s\n", error_texts[error - ERROR_INPUT]);
}
void print_error(int error)
{//what error it is
switch (error){
case ERROR_INPUT:
report_error(ERROR_INPUT);
break;
case ERROR_LEN:
report_error(ERROR_LEN);
break;
}
}
int get_sameletters(char *msg, char *msgRes, int offset)
{//gets count of sameletters between two strings
int sameLetters = 0;
for (int i = 0; i<offset-1; ++i){
if (msg[i] == msgRes[i])
sameLetters++;
}
return sameLetters;
}
int get_letter(char letter, char *alphabet)
{
int k = 0;
for (int i=0; alphabet[i]; ++i){
if (letter == alphabet[i])
k = i;
}
return k;
}
int compare(char *msgEnc, char *msg, char *msgRes, char *alphabet, int offset)
{//calculate a distance between first input string and string what will get after decryption
int distance, max_letters = 0;
for (int i = 0; alphabet[i]; ++i){
for (int j = 0; msgEnc[j]; ++j){
msgRes[j] = alphabet[(get_letter(msgEnc[j], alphabet) + i) % 52];
}
int sameLetters = get_sameletters(msg, msgRes, offset);
if (sameLetters >= max_letters){
max_letters = sameLetters;
distance = i;
}
}
return distance;
}
char *read_Input_Msg(int *msglen)
{//input messages, at the same time counts the length of the entered string
int capacity = INT_MSG_LEN;
char *msg = malloc(capacity);
int c, len = 0;
while ((c = getchar()) != EOF && c != '\n'){
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
free(msg);
msg = NULL;
len = 0;
break;
}
if (len == capacity){
char *tmp = realloc(msg, capacity * 2);
if (tmp == NULL){
free(msg);
msg = NULL;
len = 0;
break;
}
capacity *= 2;
msg = tmp;
}
msg[len++] = c;
}
*msglen = len;
return msg;
}
char rotate(char *original, int offset)
{
for (int i = 0; i<offset; ++i){
if (original[i] > 'Z' && original[i]<'a')
original[i] += 6;
else if (original[i] > 'z'){
int k = (int)original[i];
k -= 58;
original[i] = (char)k;
}
}
return *original;
}
When I run it through Valgrind, it says to me that I have errors with the allocated memory, says I do not free it. Writes that memory is not freed at 107.56 and 44 lines, more precisely
==56665== Conditional jump or move depends on uninitialised value(s)
==56665== at 0x4015BF: compare (main.c:107)
==56665== by 0x401468: shift (main.c:56)
==56665== by 0x4012C3: main (main.c:44)
==56665==
�elloword
==56665==
==56665== HEAP SUMMARY:
==56665== in use at exit: 0 bytes in 0 blocks
==56665== total heap usage: 4 allocs, 4 frees, 2,098 bytes allocated
==56665==
==56665== All heap blocks were freed -- no leaks are possible
==56665==
==56665== Use --track-origins=yes to see where uninitialised values come from
==56665== For lists of detected and suppressed errors, rerun with: -s
==56665== ERROR SUMMARY: 52 errors from 1 contexts (suppressed: 0 from 0)
好像释放了内存,但这还不够,因为一些函数调用后还有未释放的内存。我想我只是不知道如何释放它。在每个请求额外内存的函数结束时,我尝试通过 free(函数调用的数组)释放它,但在这种情况下它显示分段错误。如果您至少让我知道一些事情,我将不胜感激。
这里是输入示例
xUbbemehbT
XYlloworld
valgrind 输出不是说你有内存泄漏或者你没有正确释放一些东西。
如果您查看这部分输出:
==56665== HEAP SUMMARY:
==56665== in use at exit: 0 bytes in 0 blocks
==56665== total heap usage: 4 allocs, 4 frees, 2,098 bytes allocated
==56665==
==56665== All heap blocks were freed -- no leaks are possible
它表明所有分配的内存块都已释放。所以你没有分配问题。
重要的是这部分:
==56665== Conditional jump or move depends on uninitialised value(s)
==56665== at 0x4015BF: compare (main.c:107)
==56665== by 0x401468: shift (main.c:56)
==56665== by 0x4012C3: main (main.c:44)
这表示在第 107 行的 compare
函数(从第 56 行的 shift
调用,又从第 44 行的 main
调用),一个读取了从未初始化的值。这一行是:
for (int j = 0; msgEnc[j]; ++j){
所以这告诉我们您正在读取从未写入的 msgEnc
数组中的一个字节。该数组是在 read_Input_Msg
函数中写入的,该函数一次将一个字符读入数组。
因为这个数组应该是一个字符串,并且因为您一次读取一个字节,所以您需要手动添加一个您没有做的终止空字节。因此,当最终调用 compare
时,上面的行正在寻找一个从未明确写入的空字节,因此您最终会读取未初始化的字节。
在read_Input_Msg
中的主while
循环之后,在字符串末尾添加空字节:
while ((c = getchar()) != EOF && c != '\n'){
...
}
msg[len]=0;