【问题标题】:Memory Allocation, Outputting Garbage内存分配,输出垃圾
【发布时间】:2018-08-22 14:34:31
【问题描述】:

为什么这会在 arrayLetter 中输出垃圾而不是 char 值? 当我将for循环打印在方法调用上方的arrayLetter时,它起作用了;当我把它放在它下面时,它不起作用。我没有在方法或主体中更改 arrayLetter。这是一个简单的程序,可以移动索引并输出移动的字母。

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

int* getMatchedIndex(char arrayLetter[], char plainTextExample[],int sizeArrayLetter, int sizePlainTextExample);
int* vigenereCipherEncryptIndex(int key[], int sizeKey, int sizeArrayLetter, int sizePlainTextExample, int arrayMatchAtIndex[]);
char* convertToNewEncryptedArray(char arrayLetter[], int encryptArray[], int sizeArrayLetter, int sizePlainTextExample);

int main(void) {

    char arrayLetter[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
                           'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
                           's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};

    int key[] = { 21, 4, 2, 19, 14, 17};

    char plainTextExample[] = { 'h', 'e', 'r', 'e',
                                'i', 's',
                                'h', 'o', 'w',
                                'i', 't',
                                'w', 'o', 'r', 'k', 's'};

    int sizeArrayLetter = sizeof(arrayLetter)/sizeof(arrayLetter[0]);
    int sizePlainTextExample = sizeof(plainTextExample)/sizeof(plainTextExample[0]);
    int sizeKey = sizeof(key)/sizeof(key[0]);

    int *arrayMatchAtIndex;
    int *encryptArray;
    char *cipherArray;

    arrayMatchAtIndex = getMatchedIndex(arrayLetter, plainTextExample, sizeArrayLetter, sizePlainTextExample);
    encryptArray = vigenereCipherEncryptIndex(key, sizeKey, sizeArrayLetter, sizePlainTextExample, arrayMatchAtIndex);
    cipherArray = convertToNewEncryptedArray(arrayLetter, encryptArray, sizeArrayLetter, sizePlainTextExample);

    for(char i=0; i < sizeArrayLetter; i++)
    {
        //printf("%s%i%s", "Indexes of Encryption: ", encryptArray[i], " \n");
        printf("%s", arrayLetter);

    }


    free(arrayMatchAtIndex);
    free(encryptArray);
    free(cipherArray);

    return EXIT_SUCCESS;
}

//compare arrays and store index into array
int *getMatchedIndex(char arrayLetter[], char plainTextExample[],int sizeArrayLetter, int sizePlainTextExample)
{

    int* arrayMatchAtIndex = malloc(sizePlainTextExample* sizeof(int));

    //loop plainTextExample
    for(int i=0; i < sizePlainTextExample ; i++)
    {
        //loop arrayLetter
        for(int j=0; j < sizeArrayLetter ; j++)
        {
            //compare -> match then store arrayLetter index into arrayMatchAtIndex
            if(plainTextExample[i] == arrayLetter[j])
            {
                arrayMatchAtIndex[i] = j;
            }
        }

    }
    return arrayMatchAtIndex;
}

//encrypt array by adding 'key' indexes into array
int* vigenereCipherEncryptIndex(int key[], int sizeKey, int sizeArrayLetter, int sizePlainTextExample, int arrayMatchAtIndex[])
{
    //make new array
    int* encryptArray = malloc(sizePlainTextExample* sizeof(int));

    int j=0;

    //encrypt element -> (add elements of arrayIndexes and key) mod 26
    for(int i=0; i < sizePlainTextExample; i++)
    {

        if(i >= sizeKey)
        {
            j = (i % sizeKey);
            key[i] = key[j];
        }

        encryptArray[i] = (arrayMatchAtIndex[i]+key[i]) % 26;
    //  printf("%s%d%s%d%s", "Match Element: ", arrayMatchAtIndex[i], " key ", key[i], " ");
    //  printf("%s%d%s", "encryptElement: ", encryptArray[i], " \n");
    }

    return encryptArray;
}

//convert encrypt array index to its elements
char* convertToNewEncryptedArray(char arrayLetter[], int encryptArray[], int sizeArrayLetter, int sizePlainTextExample)
{
    char* cipherArray = malloc(sizePlainTextExample* sizeof(int));

    //encrypted index - > convert elements to new index
    for(int i=0; i < sizePlainTextExample ; i++)
    {
        for(int j=0; j< sizeArrayLetter; j++)
        {
            //find index->match then put Encrypted index into letter element
            if(encryptArray[i] == j)
            {
                cipherArray[i] = arrayLetter[j];
                printf("%c", arrayLetter[2]);
            }

        }
    }

    return cipherArray;
}

【问题讨论】:

  • 由于arrayLetter 不是以空值结尾的,所以当您使用printf("%s", arrayLetter); 打印它时会得到垃圾——没有什么可以让printf() 在到达数组末尾时停止处理。
  • 那么,解决这个问题的正确方法是什么?空终止是什么意思?
  • 在 C 中,字符串是直到第一个空字节的字符序列——空字节标记字符串的结尾,或终止它。您的 arrayLetter 中没有空字节,因此它不是字符串。 %s 格式用于打印字符串;打印非字符串会导致未定义的行为,并经常导致打印垃圾。你可以通过使用printf("%*s", (int)sizeof(arrayLetter), arrayLetter); 来修复它——* 意味着将int 值作为要打印的最大字符数,如果之前遇到空字节则停止。
  • 建议的解决方案代码似乎无法修复错误。不过,“%*s”很高兴知道。
  • @Jean-BaptisteYunès:你是对的;我打错了,省略了关键的. — 我打算使用printf("%.*s", sizeArrayLetter, arrayLetter);(或sizeof() 和演员表的等价物)。它可能相关也可能不相关,但arrayLettersvigenereCipherEncryptIndex() 覆盖,结果包含很多控制字符(主要是^B、'\002')。

标签: c memory memory-leaks vigenere


【解决方案1】:

正如 Jonathan Leffler 所说,您的数组只是一个数组,而不是 C 字符串(以 nul 结尾的字符序列)。 %s 仅与 C 字符串一起使用。

将循环更改为:

for (char i=0; i<sizeArrayLetter; i++) {
    putchar(arrayletter[i]);
}
putchar('\n');

这将单独打印数组中的所有字符和一个额外的行尾。

【讨论】:

  • 它仍然打印出垃圾。该代码是否与此相同: ~ for(char i=0; i
  • 这意味着你不小心覆盖了那个数组。
  • 是的,好像是这样。我不知道在哪里。
猜你喜欢
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
相关资源
最近更新 更多