您应该可以通过调用add_student方法将学生添加到学校,并为学生提供学生姓名和成绩的参数。
让我们说我们正在添加学生" AC Slater"等级9.如果名册已经有9级钥匙,我们就可以将AC Slater推入9级钥匙所指向的阵列中。否则,我们需要先创建9级密钥并将其指向空数组。但是,如果我们在已经存在9级密钥的情况下,我们将通过创建9的密钥并将其设置为等于空数组来擦除其当前内容!
所需行为:
school.add_student("AC Slater", 9)
school.add_student("Kelly Kapowski", 10)
school.add_student("Screech", 11)
school.roster
# => {9 => ["Zach Morris", "AC Slater"], 10 => ["Kelly Kapowski"], 11 => ["Screech"]}
到目前为止我所拥有的:
class School
attr_accessor :roster, :student_name, :school_name
def initialize(school_name)
@school_name = school_name
@roster = {}
end
def add_student(student_name, grade)
if @roster[grade] == true
@roster[grade] << student_name
else
@roster[grade] = []
@roster[grade] << student_name
end
end
end
答案 0 :(得分:1)
==6841== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60040000e000 at pc 0x400eb5 bp 0x7fff3d5302c0 sp 0x7fff3d5302b0
READ of size 8 at 0x60040000e000 thread T0
#0 0x400eb4 (/.autofs/ilab/ilab_users/xy139/night+0x400eb4)
#1 0x402911 (/.autofs/ilab/ilab_users/xy139/night+0x402911)
#2 0x7f2196abdb14 (/usr/lib64/libc-2.17.so+0x21b14)
#3 0x400a78 (/.autofs/ilab/ilab_users/xy139/night+0x400a78)
0x60040000e000 is located 8 bytes to the right of 8-byte region [0x60040000dff0,0x60040000dff8)
allocated by thread T0 here:
#0 0x7f2196e74129 (/usr/lib64/libasan.so.0.0.0+0x16129)
#1 0x402071 (/.autofs/ilab/ilab_users/xy139/night+0x402071)
#2 0x402899 (/.autofs/ilab/ilab_users/xy139/night+0x402899)
#3 0x7f2196abdb14 (/usr/lib64/libc-2.17.so+0x21b14)
Shadow bytes around the buggy address:
0x0c00ffff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 00 fa
=>0x0c00ffff9c00:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c00ffff9c50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap righ redzone: fb
Freed Heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
ASan internal: fe
==6841== ABORTING
方法的{p> if
条件:add_student
实际上永远不会按您认为的方式工作,因为当您使用不存在的密钥访问哈希时,它会返回if @roster[grade] == true
,否则为值。
当密钥不存在时:
nil
而现有的键值将被返回:
@roster = {}
@roster[9] #=> nil
因此,当密钥存在时,你比较@roster = { 9 => ["AC Slater"] }
@roster[9] #=> ["AC Slater"]
,这当然是一个错误的条件,因此你的代码总是执行if ["AC Slater"] == true
条件。因此,对于else
哈希中的成绩,您总是只有一个值。
一个小小的改变将使其发挥作用:
@roster
然而,如果你不喜欢像我这样的条件。您可以pass a block到def add_student(student_name, grade)
if @roster[grade]
@roster[grade] << student_name
else
@roster[grade] = []
@roster[grade] << student_name
end
end
存储哈希密钥的默认数组@roster
:
initialized
现在,每当您尝试在密钥不存在时获取密钥时,将执行此块,它会为其创建一个空数组,否则返回该值。因此,您现在可以安全地将def initialize(school_name)
@school_name = school_name
@roster = Hash.new{ |h, k| h[k] = [] }
end
方法更改为:
add_student